77

Does anyone have any experience with GraphQL and Firebase? I figure one would place the firebase calls in the resolver of the relevant field, passing some variable from the props of the component into the arguments of the query.

How can we insert new data in Firebase using GraphQL?

m1k3y3
  • 2,510
  • 7
  • 37
  • 65
omgj
  • 1,249
  • 2
  • 11
  • 16
  • 3
    I wrote about this here: https://medium.com/@brandon_74967/firebase-you-2017-ed-81462ef8775f – Brandon Jul 12 '17 at 22:33
  • You could try apollo-link-firebase https://github.com/Canner/apollo-link-firebase, allows you to query firebase with graphQL without backend service. – williamC Mar 27 '18 at 10:11
  • 4
    We just built an open-source tool to help you migrate from Firebase to realtime GraphQL, by actually migrating your data to Postgres. https://github.com/hasura/graphql-engine/tree/master/community/tools/firebase2graphql – iamnat Oct 08 '18 at 13:53
  • I second the previous comment. Hasura is AWESOME! – leetheguy May 13 '19 at 19:42
  • Open source project using Firebase in GraphQL server: https://github.com/rwieruch/nextjs-firebase-authentication – Robin Wieruch Feb 02 '20 at 12:42

5 Answers5

58

To answer your question, there are three ways you can deal with this.

1. Firebase & GraphQL

If you're set on using Firebase, you can make a one-to-one mapping of Firebase's API into GraphQL queries and mutations.

You can surely wrap the Firebase API into GraphQL resolvers, and make calls that way. This is a good example of that:

const ref = path => firebase.database().ref(path)
const getValue = path => ref(path).once('value')
const mapSnapshotToEntities = snapshot => snapshot.val().map((value, id) => ({ id, ...value }))
const getEntities = path => getValue(path).then(mapSnapshotToEntities)

const resolvers = {
    Author: {
        posts(author) {
            return getEntities('posts').then(posts => filter(posts, { authorId: author.id }))
        },
    },

    Post: {
        author(post) {
            return getEntities('authors').then(posts => filter(authors, { id: authorId }))
        },
    },
};

Essentially, what you're doing here is using Firebase as a database, which works until you want to query your data in a relational manner in your resolvers. Without the ability to perform joins on the server side on top of your data store, you'll be making tons of round-trip requests to Firebase in your resolvers to fulfill just a single request.

The reason most people use Firebase is for its real-time capabilities, and not primarily just as a data store since the data relational modeling tools in this aspect are fairly lacking. With that, you're probably better off migrating over to GraphQL using a different data source.

2. GraphQL Backend as a Service

Considering you're open to using BaaS products like Firebase, you might consider switching over to a GraphQL BaaS.

3. Self-hosted GraphQL

If you're open to changing over to a self-hosted solution using your own data store, there are many benefits to that as well. Here are a few big hitters:

  • Flexibility of using your own data store and perhaps multiple to suit your specific app's needs

  • Custom queries and mutations

  • Natively add custom logic instead of via microservices attached to webhooks in your API

  • Roll your own authentication and permissioning mechanisms

  • Likely a lower-cost solution

tuomassalo
  • 7,375
  • 5
  • 38
  • 48
vince
  • 1,738
  • 1
  • 8
  • 15
  • 2
    All good stuff above! Is there an example where someone has migrated off of Firebase to use Scaphold that you can provide? – Sam Mitchell Apr 24 '17 at 18:56
  • 3
    Yep! Feel free to check out [Neat App](https://app.neatanything.com) as a great app that's moved off of Firebase to use Scaphold. Please also feel free to reach out on [Scaphold's Slack](http://slack.scaphold.io) to ask others who have done so as well. – vince Apr 24 '17 at 18:58
  • 1
    Should be flagged as answer! – parohy Jul 18 '17 at 19:31
  • @vince I had read somewhere that scaphold.io is no longer in business, is that correct? (I realize the website is still up) – k00k Feb 21 '18 at 16:04
  • 1
    Now also AWS AppSync – Vyacheslav A. Apr 15 '18 at 16:05
  • The first point is accurate only if you want to use graphQL te query relationally. Firebase (RTD or firestore) are not relational databases and thoy should be modeled as no-sql databases. It is completely fine to do this but one must consider the tradeoffs – Nico May 27 '18 at 05:17
19

I strongly disagree with some recommendations here. GraphQL can be used in a relational way but it can also be used in a NoSQL way. Firebase, with its RTD (Real Time Database) and Firestore, should be modeled as a NoSQL database because it's a NoSQL database! There are tradeoffs to this approach:

1. Optimized read:

As a NoSQL database, the collections should be modeled as your views in your clients (mobile or web), so when you make a query, everything is already merged and you don't have to make computed props in the client nor Firebase functions. This approach makes reading really REALLY fast.

2. De-optimized write:

The main trade off here is that is your responsibility to update every document in the database if you touch related data (like updating the username, profile picture, etc). In this case you should find every document in your database (ie: posts, comments, etc) and ensure atomicity. This approach is recommended if you have an app that is going to have far more read operations than write operations (like a blog, 7000 reads to 1 write as an example).

3. Easy to scale:

As your collections do not have hard relationships with other documents, you can have a complete collection in only one server or split it among many of them. (That's why Firebase is cheap to scale, like DynamoDB.)

GraphQL is only a query language. It should make easy for you to query things, but it should not dictate how you model your database. You should dictate how to model your database, your queries, and mutations.

kjhughes
  • 89,675
  • 16
  • 141
  • 199
Nico
  • 1,091
  • 1
  • 11
  • 26
16

TL;DR: GraphQL shines where Firebase falls short. Powerful data modeling, flexible and efficient queries and the open specification are all essential parts of GraphQL that are lacking with Firebase.

Powerful Data Modeling

Firebase has received a lot of criticism based on its limited data modeling. Basically, your data is structured as a single, huge JSON that states the same data multiple times. What seems convenient at first results in unmanageable client code whenever you need to update data, as you have to keep track of all the references to the same data manually.

The data structure used in GraphQL on the other hand is very intuitive and familiar to think about, as it is modelled as a graph. Using the IDL syntax we can easily describe our data model, called the GraphQL schema. For a Twitter app, the schema could look like this:

type Tweet {
  id: ID!
  title: String!
  author: User! @relation(name: "Tweets")
}

type User {
  id: ID!
  name: String!
  tweets: [Tweet!]! @relation(name: "Tweets")
}

Here we defined two types Tweet and User with some scalar properties and also a one-to-many relationship between User and Tweet. Single data items are referred to as nodes - and a user node can be connected to many tweet nodes. This data structure is both simple and flexible, other than the JSON approach from Firebase.

Flexible and Efficient Queries

The flexible query capabilities of GraphQL is one its main benefits. Queries are hierarchical, that means you can specify data requirements that mirror the graph structure. In our Twitter example, we might have a query to fetch all users and their tweets:

query {
  allUsers {
    id
    name
    tweets {
      title
    }
  }
}

Note that we can freely include or leave out fields that we want to query, and we can even query across relations. This means that we neither need to do multiple queries nor are we querying unneeded data - making GraphQL queries extremely efficient.

Adding query arguments to the mix we can add features like a custom order or filters to obtain a powerful GraphQL API.

All of that is simply not possible with Firebase.

Realtime Data

Firebase's realtime capabilities have made it so popular - but since the GraphQL community is about to reach a consensus regarding realtime, Firebase's biggest advantage is nullified as well. I recommend this video tutorial on GraphQL subscriptions to get a better understanding of underlying concepts

Conclusion

So, to answer your question: GraphQL surpasses Firebases in most aspects making it the preferred choice.

If you're interested in GraphQL, I encourage you to check out Graphcool that combines the strengths of GraphQL with powerful features like built-in authentication and flexible hooks to AWS Lambda or other serverless functions to implement custom business logic.

Disclaimer: I work at Graphcool :)

marktani
  • 6,520
  • 5
  • 33
  • 59
  • 1
    @martktani I'm in the process of refactoring a react-redux-thunk-firebase project, comprised of 'posts' and 'comments', to react-redux-graphql. Is there a process in Graphcool which would enable the creation schema/nodes by importing json data from firebase? I ask as the thought of having to re-enter All the existing data one node at a time, is too painful to contemplate. – TheoG Mar 25 '17 at 07:58
  • 1
    Sorry, just saw the question! Here's [a tutorial for importing JSON data](https://www.graph.cool/docs/tutorials/importing-complex-data-aing2chaih) to GraphQL. Let me know if that helps! – marktani Apr 15 '17 at 23:49
  • Hello marktani. I see that some parts of your answer were copied from [here](https://github.com/xDae/fireQL), without explicitely making it clear that these parts were copied from that location (attribution + quoting). I am assuming you wrote the read.me from that link? If so, perhaps you could make that a bit more clear? (I was looking for copied parts, hence the comment). If not, can you make it clear by quoting the copied parts and making it clear where things were copied from. – TT. Sep 26 '17 at 12:56
  • 1
    Thanks for your question, @TT. In fact, the text in the link you reference copied the text from my answer here. – marktani Sep 26 '17 at 12:57
  • 1
    Oh I see now :) hence the backlink. Good to know. – TT. Sep 26 '17 at 12:58
7

You can use graphql & firebase locally. All the heavy lifting can be done in a webworker to avoid blocking the UI when resolving the request.

One word about the "many roundtrips necessary to resolve the request" : if you don't mind about the data transferred, that's not so much of a big deal since all the "roundtrips" are merged in the same socket frame. But if you do want to avoid big frames, you just have to put a little dataloader in front of your firebase database.

For realtime updates, you only have to subscribe to realtime events from firebase and send them to the webworker to convert them into real graphql subscriptions that can be resolved through your schema.

You can find more information on this very issue on my medium post : “Client-side only” realtime web applications with Firebase, GraphQL and apollo-client 2.0

Hope that helps !

Pierre Criulanscy
  • 7,771
  • 3
  • 20
  • 36
5

Do you have to use firebase? There are services more specific to GraphQL that may offer what you're looking for. https://scaphold.io is a YC Fellowship Company that looks particularly promising and gives you a firebase like experience but it is powered by GraphQL.

Michael
  • 99
  • 1
  • 2
    Is scaphold.io is enough followed by the community to be reliable for at least medium-term duration? – Made in Moon Jan 03 '17 at 12:01
  • 4
    Hi there, this is Vince from [Scaphold.io](https://scaphold.io) and I thought I'd chime in here. To your question, **yes** we have a very strong community following and we're not going anywhere. We've now grown to several thousand apps on the platform and currently in the YC Core program (W17). If you'd like to join in the fun, here's our Slack (http://slack.scaphold.io). – vince Mar 03 '17 at 19:25
  • 2
    scaphold is trustful, I really like the feature of the pipeline which helps you to connect all APIs in an easy way. – Amazingandyyy Apr 26 '17 at 23:26
  • 5
    aaaaaannd it's gone. Out of business. Seems like your concerns were valid @MadeInMoon – Nicolas Marshall Apr 08 '18 at 09:35
  • @NicolasMarshall well seen! Regarding Vince's answer it let me a sad taste to know that even a "strong community" can shutdown, with all human and code implications – Made in Moon Apr 08 '18 at 15:12
  • @MadeInMoon happens all the time. For lack of money or after acquisitions. And it will happen again and again... (at least until everything runs decentralized maybe) – Nicolas Marshall Apr 09 '18 at 10:11
  • Is it gone actually? – alex_1948511 Apr 17 '18 at 17:59
  • It feels like the website link given in the answer is gone, but the Github Repo remains: https://github.com/scaphold-io and also the Docs are accesible through : https://docs.scaphold.io/ – kaushalop Jan 09 '19 at 19:59