How I got Expo and react-native-firebase working in one project?
I got used to using Expo. It has many useful and ready to use libraries and an awesome Client app. Recently I’ve been working on React Native app, which used Firebase Cloud Firestore as the main database.
❗ Update 07/2021: This article has become outdated and the solution described . I’ve written a new article describing a lot better approach to this problem. You can find it here. 🔥
❌ The content below is outdated, I strongly discourage you from using the solutions described there. For a better solution, please see the update above.
The problem
When using Expo with managed workflow, installing react-native-firebase directly is impossible, because Expo doesn’t support native modules. Expo documentation says, that we have two ways:
- Use Firebase Web JS SDK
- Use Expo bare workflow
First way is easy, but limited (only few modules are supported) and slower, because we resign from native support and do everything in JS thread.
The second way allows me to install and use any native modules, but they will not work in Expo Client. When there are only few components that use native modules, that is not a big deal, but the problem starts when whole app is using on native modules. Also, we cannot use Expo build service to build and release our app.
Which one I chose? Both. I’m not using remote Expo build services, but for testing purposes it is convenient for me to use their Client. Expo has a workaround, that allows me to use proper version of Firebase SDK:
- When I run my app on Expo client, Firebase Web JS SDK is loaded
- When I build it using bare react-native, Firebase native SDK is loaded
The Solution
Fortunately, both Web and Mobile Firebase SDK has exactly same API for some modules (for example Firestore). This means we can write whole code once and it should work with both versions.
Expo allows us to create separate code files for client-specific fallbacks. Let’s create two files. One for native:
//firebaseProvider.tsconsole.log('Using Native Firestore Provider');import firestoreNative from '@react-native-firebase/firestore';
export default firestoreNative;
and one with .expo
appended to its filename:
Update: Note that since Expo SDK 41 the extension
.expo.ts
is no longer working. More details here.
//firebaseProvider.expo.tsconsole.log('Expo - Using Node.js Firestore provider');
import * as firebase from 'firebase'; import 'firebase/firestore';const firebaseConfig = {
"apiKey": "===<<<YOUR_API_KEY>>>===",
"authDomain": "===<<<PROJECT_ID>>>===.firebaseapp.com",
"projectId": "===<<<PROJECT_ID>>>==="
};firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
export default () => db;
Now, we can use Firestore anywhere in our app:
import firestore from './firebaseProvider';//example usage
const items = await firestore().collection('items').get();
Loader will automatically choose which file it should import. Of course we also need to have both Firebase SDKs installed (see their official docs for installation instructions).
What with native-only Firebase modules?
Expo still allows to disable them using simple if
statements. Quick example:
import analytics from '@react-native-firebase/analytics';//don't track screens for Expo Client - Firebase Web SDK
//doesn't support it
if (appConstants.appOwnership !== AppOwnership.Expo)
analytics().setCurrentScreen(routeName, routeName);
Project creation and Android build hell
You will probably encounter some problems, when trying to build Expo Bare app with Firebase on Android. They are caused by incompatible Gradle wrapper versions. Expo bare workflow uses react-native-unimodules
which require older Gradle versions to build, and react-native-firebase
works with newer Gradle versions. This may lead to frustrating build errors.
By trial and error method, I have it working for Gradle wrapper version 5.0. I do not guarantee that it will work for existing projects (so make your backup before doing anything), but I will explain how to create new project and configure it to work:
Used versions: Expo 36.0, Expo CLI: 3.13.8, React-Native: 0.61,
- Create new Bare Workflow expo project:
expo init <<your project name>>
---- then select Bare Workflow (with TypeScript if you prefer) ---
2. After project generation, go into its directory and install Firebase dependencies (both web and native):
cd <<your project name>>
yarn add @react-native-firebase/app @react-native-firebase/firestore @react-native-firebase/auth firebase---- For mac/iOS only ----
cd ios && pod install && cd ..
3. Modify Gradle configuration (generated one is corrupt).
- Go to
android/build.gradle
and replace:task wrapper(type: Wrapper)
with justwrapper
- Go to
android/gradle/wrapper/gradle-wrapper.properties
and indistributionUrl
replace version 4.10.1 (or any other) with 5.0 - Check if it builds, run
react-native run-android
,react-native run-ios
(mac only) andexpo start
. - Configure Firebase for your project (see Google and RN-Firebase docs)
- Try to use solution above :)