All Projects → arjunyel → Firestore Apollo Graphql

arjunyel / Firestore Apollo Graphql

Licence: unlicense
An example of a GraphQL setup with a Firebase Firestore backend. Uses Apollo Engine/Server 2.0 and deployed to Google App Engine.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Firestore Apollo Graphql

Canner
⚡️[NOT MAINTAINED] Content Management Framework creates custom CMS fast and easy. Support data sources such as Firebase/Firestore, GraphQL and Restful APIs.
Stars: ✭ 2,472 (+566.31%)
Mutual labels:  graphql, apollo, firebase, firestore
Graphql Apq
🎯 Automatic persisted queries (APQ) for any GraphQL server.
Stars: ✭ 43 (-88.41%)
Mutual labels:  graphql, apollo, apollo-server
Graphql Modules
Enterprise Grade Tooling For Your GraphQL Server
Stars: ✭ 962 (+159.3%)
Mutual labels:  graphql, apollo, apollo-server
React Hipstaplate
A ReactJS full-stack boilerplate based on typescript with ssr, custom apollo-server and huge stack of modern utilities which will help you to start your own project
Stars: ✭ 74 (-80.05%)
Mutual labels:  graphql, apollo, apollo-server
Graphql Advanced Projection
Fully customizable Mongoose/MongoDB projection generator.
Stars: ✭ 46 (-87.6%)
Mutual labels:  graphql, apollo, apollo-server
Chatty
A WhatsApp clone with React Native and Apollo (Tutorial)
Stars: ✭ 481 (+29.65%)
Mutual labels:  graphql, apollo, apollo-server
Apollo Server Vercel
⚫ Production-ready Node.js GraphQL server for Vercel Serverless Functions
Stars: ✭ 69 (-81.4%)
Mutual labels:  graphql, apollo, apollo-server
React Firebase Starter
Boilerplate (seed) project for creating web apps with React.js, GraphQL.js and Relay
Stars: ✭ 4,366 (+1076.82%)
Mutual labels:  graphql, firebase, firestore
Sapper Firebase Typescript Graphql Tailwindcss Actions Template
A template that includes Sapper for Svelte, Firebase functions and hosting, TypeScript and TypeGraphQL, Tailwind CSS, ESLint, and automatic building and deployment with GitHub Actions
Stars: ✭ 111 (-70.08%)
Mutual labels:  graphql, apollo-server, firebase
Awesome Apollo Graphql
A curated list of amazingly awesome things regarding Apollo GraphQL ecosystem 🌟
Stars: ✭ 126 (-66.04%)
Mutual labels:  graphql, apollo, apollo-server
Portara
Portara directive is a rate limiter / throttler for GraphQL
Stars: ✭ 158 (-57.41%)
Mutual labels:  graphql, apollo, apollo-server
Firegraph
GraphQL Superpowers for Google Cloud Firestore
Stars: ✭ 80 (-78.44%)
Mutual labels:  graphql, firebase, firestore
Sqldatasource
SQL DataSource for Apollo GraphQL projects
Stars: ✭ 176 (-52.56%)
Mutual labels:  graphql, apollo, apollo-server
Gqlify
[NOT MAINTAINED]An API integration framework using GraphQL
Stars: ✭ 182 (-50.94%)
Mutual labels:  graphql, firebase, firestore
Squanchy Android
Open source Android app for your conferences
Stars: ✭ 294 (-20.75%)
Mutual labels:  firebase, firestore
Babel Plugin Import Graphql
Enables import syntax for .graphql and .gql files
Stars: ✭ 284 (-23.45%)
Mutual labels:  graphql, apollo
Graphcms Examples
Example projects to help you get started with GraphCMS
Stars: ✭ 295 (-20.49%)
Mutual labels:  graphql, apollo-server
Firesql
Query Firestore using SQL syntax
Stars: ✭ 304 (-18.06%)
Mutual labels:  firebase, firestore
Ssr Sample
A minimum sample of Server-Side-Rendering, Single-Page-Application and Progressive Web App
Stars: ✭ 285 (-23.18%)
Mutual labels:  graphql, apollo
Vuefire
🔥 Firebase bindings for Vue.js & Vuex
Stars: ✭ 3,234 (+771.7%)
Mutual labels:  firebase, firestore

firebase-firestore-graphql

An example of a GraphQL setup with a Firebase Firestore backend. Uses Apollo Engine/Server 2.0 and deployed to Google App Engine.

Initial setup

npm init --yes
npm install [email protected] firebase-admin graphql graphql-tag
npm install --save-dev typescript tslint

You'll also want to set up some scripts and other settings, as of writing here is what the package.json looks like

{
  "name": "firebase-firestore-graphql",
  "scripts": {
      "build": "tsc",
      "serve": "npm run build && node lib/index.js",
      "start": "node lib/index.js",
      "deploy": "npm run build && gcloud app deploy"
  },
  "main": "lib/index.js",
  "dependencies": {
      "apollo-server": "^2.0.0-beta.10",
      "firebase-admin": "^5.12.1",
      "graphql": "^0.13.2",
      "graphql-tag": "^2.9.2"
  },
  "devDependencies": {
      "tslint": "^5.10.0",
      "typescript": "^2.9.1"
  }
}

Firebase setup

Download Firebase service account as service-account.json and put in root of this directory.

In your firestore database setup two collections, one of tweets and one of users. The userId in tweets should point to a user Id that the tweet came from.

interface User {
  id: string;
  name: string;
  screenName: string;
  statusesCount: number;
}

interface Tweet {
  id: string;
  name: string;
  screenName: string;
  statusesCount: number;
  userId: string;
}

Typescript

Copy the tslint and tsconfig json files from this repo into your own.

GraphQL

Make a src directory and a index.ts file inside. Setup the imports

import * as admin from 'firebase-admin';

const serviceAccount = require('../service-account.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

import { ApolloServer, ApolloError, ValidationError, gql } from 'apollo-server';

interface User {
  id: string;
  name: string;
  screenName: string;
  statusesCount: number;
}

interface Tweet {
  id: string;
  name: string;
  screenName: string;
  statusesCount: number;
  userId: string;
}

Schema

Now we setup our GraphQL schema

const typeDefs = gql`
  # A Twitter User
  type User {
    id: ID!
    name: String!
    screenName: String!
    statusesCount: Int!
    tweets: [Tweets]!
  }

  # A Tweet Object
  type Tweets {
    id: ID!
    text: String!
    userId: String!
    user: User!
    likes: Int!
  }

  type Query {
    tweets: [Tweets]
    user(id: String!): User
  }
`;

The ! signifies that this property is guaranteed to not be null. You'll notice that a user has an array of Tweets and a tweet has a user object in it, despite them being separate collections in our database. This is the magic of GraphQL, we can combine things across collections.

For the purpose of this tutorial we have two queries, an array of all tweets and a specific user based on their ID.

Resolver

Next we setup our resolver, this turns GraphQL queries into data. First we setup our resolver for the base queries

const resolvers = {
  Query: {
    async tweets() {
      const tweets = await admin
        .firestore()
        .collection('tweets')
        .get();
      return tweets.docs.map(tweet => tweet.data()) as Tweet[];
    },
    async user(_: null, args: { id: string }) {
      try {
        const userDoc = await admin
          .firestore()
          .doc(`users/${args.id}`)
          .get();
        const user = userDoc.data() as User | undefined;
        return user || new ValidationError('User ID not found');
      } catch (error) {
        throw new ApolloError(error);
      }
    }
  }
};

This will get an array of tweets or a user but how do we add the graph part of GraphQL and interconnect different collections such as all the Tweets a user has made or the details of a user that made a certain tweet?

const resolvers = {
  Query: {
    ...
  },
  User: {
    async tweets(user) {
      try {
        const userTweets = await admin
          .firestore()
          .collection('tweets')
          .where('userId', '==', user.id)
          .get();
        return userTweets.docs.map(tweet => tweet.data()) as Tweet[];
      } catch (error) {
        throw new ApolloError(error);
      }
    }
  },
  Tweets: {
    async user(tweet) {
      try {
        const tweetAuthor = await admin
          .firestore()
          .doc(`users/${tweet.userId}`)
          .get();
        return tweetAuthor.data() as User;
      } catch (error) {
        throw new ApolloError(error);
      }
    }
  }
};

Take getting all the tweets a user has made as an example. You can see in our resolver we have a user object with a tweets property. Because tweets is a child of user, we can use the parent user to then query the tweets collection for all the tweets with that user ID.

Apollo Server

Finally we setup our Apollo server, to work on App Engine we need to grab the port from the enviroment variables

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: true
});

server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

If you setup your npm scripts you should be able to run

npm run serve

If you navigate to the URL you shoud be able to see a GraphQL playground where you can query your API, congrats!

Apollo Engine

Apollo Engine gives use awesome features such as caching, tracing, and error logging. First get an Apollo Engine API key then change your Apollo server config to turn on engine

const server = new ApolloServer({
  typeDefs,
  resolvers,
  engine: {
    apiKey: "<APOLLO ENGINE API KEY HERE>"
  },
  introspection: true
});

Now when you npm serve and run some queries you should see some data populate the Apollo Engine dashboard with things like how fast your queries resolved. Cool!

App Engine

Finally we can deploy to App engine so the world can access our GraphQL endpoint. In the root project folder create a file app.yaml. Inside is just one line

runtime: nodejs8

Also add the .gcloudignore file from this repo to your folder. Setup the gcloud SDK then point it to your Firebase project.

gcloud config set project <projectID>
npm run build
gcloud app deploy

You should get a deployed URL, you can then query that using an GraphQL tool. I personally use Insomnia’s GraphQL mode.

Congratulations, you've setup a GraphQL server!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].