Integrating the Firebase Web SDK into a website is usually straightforwards; install the firebase
NPM package, import it and off you go! Doing this with Gatsby JS will cause some issues.
When building your project for production, Gatsby creates static files which are built on a machine. This build environment has no access to the window
object. The Firebase Web SDK is not server friendly, and assumes its environment always has access to the window
. If you simply import Firebase and expect it to work out of the box, you'll hit a bunch of issues when during the static build process. So how do you overcome this?
Exporting a Firebase instance #
Firstly, we need to export a Firebase instance in our project. However, we only want this to happen when the window
is available, otherwise we skip the initialization of Firebase.
In your project, install Firebase via NPM (npm install firebase
), then create a firebase.js
file using your project credentials from the Firebase Console:
What's happening here? We're exporting a function called getFirebase
which creates a new Firebase instance when called, only if the window
object is available (on the client). If the window
is available, and an instance has already been created, we return the cached one (for example if multiple components require Firebase usage).
Great; we can now initialize Firebase during build time with no errors!
Accessing Firebase from a component #
The next problem we have is being able to access Firebase within a component & being able to use it. Luckily, we can take advantage of React Hooks to make the accessing of the exported Firebase instance simple.
Create a new hook in your project, for example a file called useFirebase.js
:
This hook allows us to subscribe to whenever the Firebase instance is available. On the server, null
will be returned however once the client is available the instance is passed back.
To use this within a component, we can import the hook and use the hook useEffect
to synchronize with the Firebase instance:
Now we can use Firebase functionality whenever the instance is available, only on the client.
Summary #
The following approach is as cleanest I've found when working with both Firebase & GatsbyJS - it removes most of the "hacking" aspect away from core logic, not having to worry about whether the window is available.
If anyone has found a better way to integrate the two together, please reach out to me on Twitter - I'd love to make the integration as seamless as possible!