Yes, you can query Firebase with GraphQL.

And you can do it with nothing but Cloud Functions.

Luke Pighetti
4 min readDec 2, 2018

--

Hi everyone! This is my first post on Medium and I’m super stoked to share the marriage of two of my favorite technologies: GraphQL and Firebase.

Last meme, I swear.

Why GraphQL with Firebase?

Firebase is an awesome platform for developers. It’s a one-stop-shop for authentication, hosting, database, and serverless cloud functions. It is realtime first and it has a very generous free tier and awesome tooling. But it has one achilles heel: querying the database. GraphQL provides a very dynamic and expressive query layer and can vastly simplify fetching operations for Firebase clients.

Why Apollo Server 2?

apollo-server-express is very lightweight, easy to wire up, and pairs well with Firebase Cloud Functions. That makes it cheap, cheap, and cheap.

Let’s go!

This tutorial assumes you know the basics of Firebase CLI and setting up Node projects.

Create a Firebase project

Then create a project folder and initialize the project with Functions. This project uses JavaScript.

firebase init# ❯◉ Functions: Configure and deploy Cloud Functions

Install dependencies

cd functions
npm install
npm install apollo-server-express express graphql

Craft src/index.js

Preamble brings everything you need into src/index.js

const admin = require("firebase-admin");
const functions = require("firebase-functions");
const express = require("express");
admin.initializeApp();const { ApolloServer, gql } = require("apollo-server-express");

TypeDefs describe your GraphQL schema to Apollo Server.

const typeDefs = gql`
type Hotdog {
isKosher: Boolean
location: String
name: String
style: String
website: String
}
type Query {
hotdogs: [Hotdog]
}
`;

Resolvers mimic your TypeDefs and tell Apollo Server where to find your data. Since Firebase returns an object and GraphQL is expecting an array, we need to extract the values.

const resolvers = {
Query: {
hotdogs: () =>
admin
.database()
.ref("hotdogs")
.once("value")
.then(snap => snap.val())
.then(val => Object.keys(val).map(key => val[key]))
}
};

Cloud Functions are triggers exported by index.js. Our particular trigger is an https.onRequest() trigger which returns an ApolloServer via Express.

const app = express();
const server = new ApolloServer({ typeDefs, resolvers });
server.applyMiddleware({ app, path: "/", cors: true });
exports.graphql = functions.https.onRequest(app);

Add data to Realtime Database

Open up Realtime Database in Firebase Console and import your data.

{
"hotdogs" : {
"hebrew_national" : {
"isKosher" : true,
"location" : "New York City",
"name" : "Hebrew National",
"style" : "Kosher Beef",
"website" : "https://www.hebrewnational.com"
},
"oscar" : {
"isKosher" : false,
"location" : "Chicago",
"name" : "Oscar Mayer",
"style" : "Ballpark",
"website" : "http://www.oscarmayer.com/"
},
"wa_beans" : {
"isKosher" : false,
"location" : "Bangor",
"name" : "W.A. Bean",
"style" : "Maine Red Snapper",
"website" : "https://www.beansmeats.com"
}
}
}

Shoutout to W.A. Bean for making a mean red snapper!

Why did I select Realtime Database? Because its blazing fast, Cloud Functions can query it for less cost than Cloud Firestore, and you can write a schema stronger than Fort Knox with Bolt and get compiled Typescript interfaces for free. But that’s another tutorial!

Be sure to make engineering decisions based on your project’s requirements, not what some guy on Medium says.

Launch GraphiQL Playground

Serve it locally to play around with it.

firebase serve

Boom.

You can’t always get what you want. Unless you’re using GraphQL.

Note: GraphiQL may not have the correct endpoint on first launch. Paste the URL into the endpoint address bar to make the connection.

Deploy it

Your production endpoint will be shown in Firebase Console > Functions.

firebase deploy

Note: GraphiQL Playground is not available in production by default.

We’re done!

Congratulations! You’ve just setup a serverless GraphQL endpoint that queries Realtime Database and doesn’t rely on any services outside of Firebase!

Next Step: Complex Queries and Mutations

This simple example is all you need to get started with GraphQL on Firebase, but there are still many unanswered questions. Those with Firebase experience need only brush up on GraphQL basics to handle complex queries and mutations. As I like to say, you just have to put in the hours.

I intend to continue this series with more examples that cover complex queries and mutations in the coming weeks. Until then, keep up the good work!

--

--