It was this, or some boring picture of two logos. I stand by my decision.

Cover your BaaS: Firebase, GraphQL, and your next project

Firebase launched in 2011. It was, by most measures, a simpler time: Node.js was a precocious 2-year-old, Wolf Blitzer had never said the word “pussy” on-air, and real-time web stuff was hard. Firebase changed one of these things, and in so doing, became a household name for developers seeking a backend-as-a-service (BaaS) with the holy trinity of fast, cheap, and easy.

Fast-forward to 2017, and Google (who owns Firebase (who owns the BaaS market)) is evolving their database product into a full-fledged (mostly mobile) app building platform. With most competing BaaS products having shuffled off this mortal coil, options for starting a new project are: Do a ton of stuff yourself, or use Firebase.

But things, as they’re wont to do, change: in the go-go world of the ‘17s, developers have options. In this post, I’m going to compare Firebase to one of those options: a GraphQL-as-a-service platform called called scaphold.io.

GraphQ-wha?

Graph Query Language, or GraphQL, is Facebook’s attempt at addressing the shortcomings of RESTful APIs. This post isn’t an in-depth look at GraphQL, but for the purposes of comparison, think of a GraphQL server like an old-timey phone operator. It sits atop your app’s backend (not, as I’d initially thought, in lieu of your backend) & knows where to find the different entities that make up your app’s schema (e.g., User, Group, PokeMan¹.). When your client makes a call, instead of calling directly to a specific endpoint, they call GraphQL, which routes their call to the data they need. The significance of this might not be apparent, but I think it’ll become more clear through comparison to Firebase.

Like Firebase, GraphQL can make frontend clients a lot less dependent on managing backends. Unlike Firebase, though, you have to actually build a GraphQL server, and this is where a new generation of BaaS come in. Essentially GraphQL-aaS, they run the entire backend operation, allowing you to build GraphQL clients as easily as (or easier than) Firebase would.

The comparison

Comparisons are hard to write, so I’m going to make it simple and make hard recommendations for different use-cases. By way of bona fides, I’ve built precisely one app on each of Firebase and Scaphold.io (a GraphQL-aaS).

(Side-note: Scaphold isn’t the only GraphQL-as-a-Service in town, they’re just the only one I’ve used. Their chief competitor, Graph.cool offers a product that differs from Firebase in the same ways Scaphold does.)

Building a mobile-only app? Firebase

Firebase has added around half-a-dozen cool new features to their product in the past year or two: integrated analytics, push notifications, and even app A/B testing, all from your Firebase console — as close to a 1-stop-shop as a dev could hope for.

Symbols representing the platforms supported by Firebase’s newest features. If I was looking for tea leaves to read about Firebase’s future, these would be a good start.

A mobile dev, that is. If your app has a significant web app (or Electron, or React Native, I think) component, most of these features won’t be available to you. Given Google’s parallel push for Progressive Web Apps, it’s disappointing how opaque Firebase has been on the roadmap for web. Because of this drought of web SDK features, web app developers considering Firebase in 2017 are essentially looking at a 2013 feature set. If you’re a web dev who values using a product actively developed by its owners, this makes Firebase a tough sell.

But, if you are a mobile dev, go Firebase. While Scaphold et al do make mobile easier than doing it yourself (like push notifications on Android & iOS), the services are smaller, younger and, on at least the features front, can’t hold (*ahem*) a candle to Firebase (sry).

Have relational data? GraphQL

Ask anyone who’s ever been dressed-down by some guy named Walter² on HackerNews or StackOverflow: tempers run hot in the NoSQL vs. SQL debate. Since I have a cat who depends on me, I’m not risking my neck to endorse one or the other here. But, since Firebase’s flavor of NoSQL schema presents some pretty significant challenges with relational data, we’ll have to unpack this point a bit.

In SQL, if you have users & groups, the process for retrieving, adding or removing members from a group is as simple as as a single operation. This is thanks to the power of relationships & such.

Firebase requires (and thus, encourages) a different approach: in order to fetch a group’s users, you have to retrieve that group by its ID and then, in the client, send new requests for each user’s profile. As you can imagine, after the first few relationships in your schema, you’re making quite a few round trips to the server (though Firebase is fast, and this seems to work well in practice).

The real problem with this, though, is state management. When the client bears responsibility for that much complex fetching logic, the room for error widens considerably. For me, it eventually felt less like Firebase was abstracting-away the backend, and more like it was putting the backend into the client.

This is where GraphQL shines. A GraphQL query for a group and all its users is as simple as:

group {
users {
edges {
node {
firstName
lastName
email
}
}
}
}

Don’t let the indentation fool you: this isn’t Callback Hell. Instead, true to its namesake, GraphQL lets you conceptualize your schema as an actual graph, where entities ( User, Group) are the nodes, and relationships are the edges. In a single round trip to the server, you can traverse relationship edges & fetch precisely the data you need.

Projects are just beginning to tap the power this brings to client-side tech. With Facebook’s Relay, for example, you merely point your app to your GraphQL endpoint & declare which pieces of data each component needs, letting the library handle the rest. Imagine: fetching data for your entire app without writing even a single line of async code.

The tradeoff for this is development speed. Someone’s got to tell GraphQL where your entities live, so you’ll have to build your schema before you use your database. But, while Firebase’s carefree schemaless design might make it faster to get started, in my experience, Scaphold’s Schema Builder UI makes the difference in speed negligible.

So, any app with a relational schema should stick with GraphQL-aaS.

Need to query? GraphQL

A Firebase project isn’t a collection of JSON documents, but instead one big-ass JSON (1BAJ). In Javascript terms, instead of this:

Users: [
{ id: 1, name: 'brandon' },
{ id: 2, name: 'emily' }
]

You have this:

Users: { 
1: {
name: 'brandon'
},
2: {
name: 'emily'
}
}

This has a few impacts on the development experience. First, Firebase’s querying ability is limited. To borrow from their docs, if you had a collection of dinosaurs with a height property, the closest you could come to a query would be sorting the collection by height & fetching the top n results. If you need more, you’ll have to load the data into client state & query it locally — in other words, more room for error. While being able to sort dinosaurs by height accounts for about 80% of my querying needs, this makes that last 20% tricky.

The second impact is a little more subtle: lists & aggregations. It feels silly to write, but if you wanted to count your dinosaurs from the previous example, you’d have to download the entire collection — including each field for every dinosaur — before performing the count operation in the client side. This might seem like a trivial example, and there are (tedious) ways around it (e.g., incrementing and decrementing a total with each addition/deletion), but imagine working with a collection of tens of thousands of records. At that point, you start to wonder whether or not maintaining a backend was really all that bad in the first place.

There isn’t much to write about Scaphold or GraphQLaaS by comparison, because querying is as powerful as it ever was with plain SQL. Filtering, sorting, and aggregating records is as simple as writing any other query. Better still, GraphQL isn’t limited to fetching data from a database, so it’s possible to integrate other APIs into your data fetching calls — e.g., fetching coordinates & resolving them to an address via the Google Places API in a single query of your GraphQL endpoint.

If your querying needs extend beyond identifying the top 5 tallest dinosaurs, go with GraphQLaaS.

Want type-safety? Probably GraphQL

This point is closer to a tossup than the previous few. On the one hand, Firebase’s authorization & validation system is pretty powerful. Using a Javascript-like language, you can determine whether or not a read/write operation is permitted based on any number of arbitrary criteria. Is the value of some field in a different part of the database a 5 when it should be a 6? Read denied. Is this user’s submission a string of 17 characters when you wanted 16? Write denied. It’s that straightforward.

Scaphold, on the other hand, doesn’t offer much by way of data validation beyond primitive type (number, boolean, etc.), basic structures (e.g., JSON, List) and string enums ('CAT' or 'DOG'). With both role and relational permissions on the row-level, authorization should be sufficient for most needs, but it still isn’t as flexible as Firebase.

All that said, though, I think I recommend GraphQLaaS in this instance. While Firebase’s validation/authorization system is definitely more powerful, it’s also (a) more complex to implement, and (b) optional.

Complexity is expected, given that it’s a proprietary language. But Scaphold’s schema builder GUI makes implementing good-enough validation/authorization a breeze. Because it’s not optional, though, I’m guessing it brings more stability on average than Firebase’s system.

Like they say about working out or unit testing: the best system is the one you’ll use, and GraphQLaaS’ compulsory typings are a better option for most than Firebase’s complexity & optional nature.

Need real-time? Firebase

While Scaphold & other GraphQL-aaS support real-time subscriptions (which, it should be noted, aren’t the same as live queries), the simplicity just can’t match Firebase yet. This isn’t surprising: Firebase’s team built the product from the ground-up with subscriptions in mind, whereas GraphQL sought to solve a broader range of problems.

If you just want a feature or two to have real-time capabilities, GraphQL-aaS might still work (hell, you can even use it alongside Firebase for some use cases). But, if you’re building something where real-time is critical, use Firebase.

The conclusion

For Wayhome, Scaphold & GraphQL were the easy choice. Our data was just too relational to reliably manage it on the client, even with power-tools like Redux & MobX. Coupled with Relay, GraphQL allows us to do-away with almost all of our client-side state management, substantially reducing the risk of sneaky bugs.

Firebase, while its positioned as general-purpose solution, is clearly optimized to solve a fairly narrow & specific set of problems. If those problems aren’t yours, think twice before building on Firebase — don’t let yourself get… burned.

Firebase & GraphQL are so significantly different that no comparison can really communicate every point worth considering. If yours are considerations I didn’t cover in this article, post a comment or email me & I’m happy to chat.

1: …[sic]. back
2: What Walt lacks in social graces, he makes up for in SO rep³. back
3: And 143,412 posts edited! back