How to integrate react-native-firebase with Expo
Over a year ago I wrote an article about a kind of hacky way to use react-native-firebase in Expo app. But things have changed significantly since then. In this article, I’m going to show you the new, much easier way to do this.
This is also a getting started guide for new features that Expo has released recently.
TL;DR Scroll down, there’s a tutorial down below. 😉
A long time ago…
It was Expo SDK 36’s when I was trying to integrate native Firebase with an Expo app. It was a tough time because Expo barely supported custom native code. That is — I had to eject to bare workflow in order to be able to use any native library. And ejecting meant that I couldn’t use
expo build anymore to build my app. Expo Client (now called Expo Go) didn’t support custom native code either.
My solution was working, but it was very cumbersome to maintain in further project stages. I had to take care of both bare and managed app separately. Things like permissions, app icon, or splash screen required separate steps for Android, iOS and managed app. Nightmare.
The new, right way!
Fortunately, Expo made huge progress! Thanks to the config plugin system, managed apps can be easily prebuilt to generate native projects, also with third-party libraries. Their new EAS Build service can build both managed and bare (!) apps. And recently released development clients allow you to build your own, customized Expo Go with any native code you wish! Impressive, isn’t it?
Ok, I’m hyped about that new wonderful Expo stuff, but what does it mean in the context of my Firebase integration? Let me explain briefly:
- Instead of the Expo Go app, I’m using my custom development client with react-native-firebase bundled with it.
- Each time I need a native change, e.g. install a native library, I rebuild my Dev Client using either EAS Build or locally using
expo run:ios. You can read more about these commands in this blog post.
- If a native library requires custom configuration — e.g. adding some code or modifying Android manifest, that configuration is applied during prebuilding phase thanks to Config Plugins.
- A prebuild is actually very similar to eject, but its name no longer sounds like it’s a one-way ticket. It’s designed to be run multiple times, without losing the possibility to use Expo managed features.
Cool, but… how to make it work? 🤔 A detailed step-by-step guide is here!
Ok, that was so much talking. Let’s dive straight into the actual solution:
First of all, ensure that you have the latest
expo-cli installed. You can quickly do it with
yarn global add expo-cli.
1. Start a project
If you have an existing managed Expo project, you can use it here, but please git commit first to make a checkpoint. I wouldn’t recommend using bare projects since prebuilding has undefined behavior on existing native projects! This doesn’t mean that you can’t use development clients in bare apps — you just have to install it manually.
Tip: When creating new project, you can run
npx create-react-native-app -t with-dev-clientto have a custom development client already set up. However, I decided to show more manual/universal solution, which should also work for existing projects.
I chose to start a new managed project and selected a blank (TypeScript) template:
2. Set up a development client
We want to develop our app with a custom development client. In order to do that, install a proper module:
expo install expo-dev-client
This package makes your debug native configuration build a custom development client. The release configuration remains unchanged; it builds a production app without the
expo-dev-client code included, aside from a few header files.
Since you’ll be building your app anyway, you can skip this step for now and come back later. If so, jump straight to Firebase installation.
When running commands from below for the first time, you’ll be asked for Android Application ID (package name) and iOS Bundle Identifier, unless you have provided them earlier in
Try to build and start your dev client by running either
expo run:android or
expo run:ios. Alternatively, you can also use EAS Build to do the job, but unless you created a project from
with-dev-client template, you’ll have to configure
eas.json yourself (you can use
eas build:configure to automate this).
expo runcommands start Metro bundler by default unless
--no-bundlerflag is provided. To start the bundler without triggering the build process, use
expo start --dev-client.
If everything goes well, after a short while you should see your custom development client running on an emulator.
3. Install Firebase
Now you can install react-native-firebase JS libraries of your choice. In my app I want to use the Firestore module:
expo install @react-native-firebase/app @react-native-firebase/firestore
In the meantime, you need to open the Firebase Console and create Android and iOS apps for your project. You’ll be asked about Android App ID and iOS Bundle Identifier. You have to provide the same values that you typed in earlier.
Please download the
GoogleServices-Info.plist — we’re going to need them in a moment.
Are we ready? Almost. When you visit the react-native-firebase website, you can see that installation steps require native changes. This is where config plugins unleash their power. A plugin’s purpose is to apply native configuration changes each time when building with EAS Build or running
expo prebuild /
expo run, without bothering you with native stuff.
Fortunately, React Native Firebase (since version 12.4.0) is shipped with some built-in plugins, which do all the necessary configuration. If the plugins weren’t shipped, you’d need to read the config plugins guide, but because they are, all you have to do is to add them to the
plugins section in your
app.json and provide paths to Google-Services files. Your
app.json file should contain these lines:
If, for some reason, you need to use older React Native Firebase version than 12.4.0, you can use the
with-rn-firebase plugin, which has very similar functionality.
The plugin idea doesn’t only apply to Firebase; it applies to any native library that requires additional configuration after linking. Since the config plugins API is pretty new, there aren’t yet many libraries that support config plugins. That’s a large area for open-source contributors. You are very welcome to help developing config plugins for your favourite libraries!
4. Run your app
Now, all that’s left to do is to build your app again (EAS Build /
expo run) and you are free to start using Firebase!
This way you have set up react-native-firebase in your own custom Expo Go… I mean development client 😅. Of course, the stuff described in this article is only the tip of an iceberg. There are many more awesome features, including a customizable developer menu. You may also want to share your custom dev client with your team/friends, or even automate it with the CI. You can learn more about all that stuff in Expo Docs.