Skip to content

Instantly share code, notes, and snippets.

@danielkcz
Last active January 11, 2019 12:40
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danielkcz/e9c79301761859c111b9b1ff6880ff0e to your computer and use it in GitHub Desktop.
Save danielkcz/e9c79301761859c111b9b1ff6880ff0e to your computer and use it in GitHub Desktop.
Firebase authentication with Graphcool
const functions = require('firebase-functions')
const admin = require('firebase-admin')
// This is hosted using Firebase Functions to gain easier access without meddling with service key
admin.initializeApp(functions.config().firebase)
exports.verifyToken = functions.https.onRequest((req, res) => {
const { idToken } = req.query
if (!idToken) {
res.json({ error: 'Missing idToken in query' })
return
}
admin.auth().verifyIdToken(idToken)
.then(authUser => res.json(authUser))
.catch(() => res.json({ error: 'Could not verify id token with Firebase' }))
})
import { fromEvent } from 'graphcool-lib'
import fetch from 'node-fetch'
import VError from 'verror'
const FIREBASE_VERIFY_URL = 'Use Firebase Functions to get one'
export default function authenticate(event) {
const graphcool = fromEvent(event)
const api = graphcool.api('simple/v1')
return verifyToken(event.data.idToken)
.then(ensureUser(api))
.then(appendGeneratedGraphcoolToken(graphcool))
.then(result => ({ data: result }))
.catch(error => ({ error }))
}
function ensureUser(api) {
return data => getGraphcoolUser(data.uid, api).then((User) => {
if (User === null) {
return createGraphcoolUser(data, api)
}
return User
})
}
function getGraphcoolUser(uid, api) {
return api.request(`query {
User(uid: "${uid}"){
id, uid, name, email
}
}`)
.then(({ error, User }) => {
if (error) {
return Promise.reject(new VError(error, 'Failed at getting graphcool user %s', uid))
}
return User || null
})
}
function createGraphcoolUser({ uid, name, email }, api) {
return api.request(`mutation CreateUserMutation {
createUser(uid: "${uid}", name: "${name}", email: "${email}") {
id, uid, name, email
}
}`).then(({ error, createUser }) => {
if (error) {
return Promise.reject(new VError(error, 'Failed at creating graphcool user %s', uid))
}
return createUser.user
})
}
function appendGeneratedGraphcoolToken(graphcool) {
return user => graphcool.generateAuthToken(user.id, 'User').then(token => Object.assign({ token }, user))
}
function verifyToken(token) {
return fetch(`${FIREBASE_VERIFY_URL}?idToken=${token}`)
.then(res => res.json())
.then((data) => {
if (data.error) {
return Promise.reject(new VError(data.error, 'Failed verifying idToken %s', token))
}
return data
})
}
import resolve from 'rollup-plugin-node-resolve'
import buble from 'rollup-plugin-buble'
// This is optional and used to transpile graphcool.authenticate.js to ES5
// If you don't want additional build step, you have to rewrite manually.
export default {
format: 'cjs',
plugins: [
resolve(),
buble(),
],
external(id) {
return !(id.startsWith('graphcool'))
},
}
@amicohn
Copy link

amicohn commented Jan 11, 2019

Dear Daniel

Im sorry sudden message.
Always thank you very much for your nice code.
Im interested in your repository very much.
https://gist.github.com/FredyC/e9c79301761859c111b9b1ff6880ff0e
I'm a beginner of a program and poor at English.
Please tell me about my question.

Firebase authentication with Graphcool

deploy to firebase functions
firebase.functions.js(yourcode)

deploy to graphcool
graphcool.authenticate.js(yourcode) & schema-extension.graphql

Question

Then what should I write in schema-extension.graphql?
(or necessary SCHEMA/TYPES)

All regards. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment