DEV Community

Gonzalo Pozzo
Gonzalo Pozzo

Posted on

Using Firebase with Gatsby

I struggled a lot with this because you don't have the window object when trying to initialize firebase, so every post I found in how to solve it propones to create a method to check if it was initialized and save the instance to a variable.

I don't like that, I just want to use it without caring if I have to initialize it or not.

This is how I solved it:

import firebase from "firebase/app";

import "firebase/auth";
import "firebase/firestore";

export default new Proxy(
  {
    get database() {
      return firebase.firestore();
    },
    get auth() {
      return firebase.auth();
    },
    providers: {
      get google() {
        return new firebase.auth.GoogleAuthProvider();
      },
    },
  },
  {
    get: function(target, name) {
      if (!firebase.apps.length) {
        firebase.initializeApp({
          apiKey: process.env.GATSBY_API_KEY,
          authDomain: process.env.GATSBY_AUTH_DOMAIN,
          databaseURL: process.env.GATSBY_DATABASE_URL,
          projectId: process.env.GATSBY_PROJECT_ID,
          storageBucket: process.env.GATSBY_STORAGE_BUCKET,
          messagingSenderId: process.env.GATSBY_MESSAGING_SENDER_ID,
          appId: process.env.GATSBY_APP_ID,
        });
      }

      return target[name];
    },
  }
);
Enter fullscreen mode Exit fullscreen mode

This way we always check if firebase is initialized without the need of doing it explicitly, just be sure to have the window object when you call a method.

Example of use:

import firebase from "../firebase";
import { IUser } from "../session";

import { ITodo } from "./types";

export default {
  add: (user: IUser["uid"], todo: Partial<ITodo>) =>
    firebase.database
      .collection("users")
      .doc(user)
      .collection("todos")
      .add(todo),
  update: (user: IUser["uid"], todo: ITodo) =>
    firebase.database
      .collection("users")
      .doc(user)
      .collection("todos")
      .doc(todo.id)
      .update(todo),
  remove: (user: IUser["uid"], id: ITodo["id"]) =>
    firebase.database
      .collection("users")
      .doc(user)
      .collection("todos")
      .doc(id)
      .delete(),
  onChange: (user: IUser["uid"], callback: (todos: ITodo[]) => void) =>
    firebase.database
      .collection("users")
      .doc(user)
      .collection("todos")
      .onSnapshot(snapshot => callback(snapshot.docs.map(doc => ({ id: doc.id, ...(doc.data() as ITodo) })))),
};
Enter fullscreen mode Exit fullscreen mode

You can find the full repo where this is being used in here:
https://github.com/goncy/typescript-firebase-context-gatsby-todos

Top comments (2)

Collapse
 
calag4n profile image
calag4n

Thank you very much, I was stuck with that !
Btw I didn't know the Proxy object.

Collapse
 
emilgfiperu profile image
EmilGFIPERU

hello, very good your post worked well for me, would you have an example of how to use push notifcation with firebase?