Using Firebase Analytics with Expo

Published: 2020-03-31 22:19:35

With the release of SDK 37.0.0, Expo now supports **native Firebase Analytics 📈** in both Managed and Bare workflows. This release also includes some core enhancements  toward supporting more native Firebase services 🔥 in the future.

Read on for instructions to get set up to record your first event, and more detail about how testing will work inside the Expo Client.

## **Installation**

To get started, install both `expo-firebase-core` and `expo-firebase-analytics` into your project.

```shell
expo install expo-firebase-core expo-firebase-analytics
```

> _`expo-firebase-core` is another new package, it helps with automatically configuring Firebase on web and native._

## **Create a Firebase project**

If you have done this already then you're good to go. Otherwise, [go to the Firebase Console](https://console.firebase.google.com/) and create your project.

## **Configuration**

Before you can start using Firebase Analytics, we'll need to add your Firebase project configuration to your Expo app. Firebase is configured using "Google Services" configuration files. We need to register iOS and Android apps to the Firebase project.

## **Register iOS and Android apps**

If you haven't built a standalone app yet, now would be a good time to come up with a `bundleIdentifier` for iOS and a `package` for Android ([more on that here](https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#2-configure-appjson)) -  you will need these for your Firebase project configuration.

## **Register a web app**

It's important to also [register a web app](https://firebase.google.com/docs/web/setup) with your project and keep the web configuration handy because we will need it in the next step. This is used to test Firebase Analytics in the Expo client app and when running your app on the web.

## **Add the Firebase configuration to app.json**
We need to now refer to this configuration on iOS, Android, and web inside of `app.json`, as follows:

```json
{
  "expo": {
    "ios": {
      "googleServicesFile": "./GoogleService-Info.plist"
    },
    "android": {
      "googleServicesFile": "./google-services.json"
    },
    "web": {
      "config": {
        "firebase": {
          "apiKey": "AIzaXXXXXXXX-xxxxxxxxxxxxxxxxxxx",
          ...
          "measurementId": "G-XXXXXXXXX"
        }
      }
    }
  }
}
```

Confused? Learn more in the detailed guide on how to setup native Firebase with Expo.

## **Basic usage**

Once configured, you can now use `logEvent` to record events.

```js
import * as Analytics from 'expo-firebase-analytics'; 
Analytics.logEvent('share', {
  contentType: 'text', 
  itemId: 'Expo rocks!', 
  method: 'facebook'
});
```

> _Depending on the platform that you are on, it may take up to an hour for the event to show up in the Firebase Analytics console. [Read more about it here](https://firebase.googleblog.com/2016/11/how-long-does-it-take-for-my-firebase-analytics-data-to-show-up.html)._

You can also associate additional user information with your events, so you can track specific audiences. Calling `setUserId` and `setUserProperties` will not record an event in itself, but transmit that information with every recorded event thereafter.

```js
Analytics.setUserId('saitama');
Analytics.setUserProperties({
  hero_class: 'B',
});
```

## **Automatic event tracking**

Besides manual event logging, the native Firebase SDKs also tracks events automatically. Things like `first_visit` and `first_open` are recorded on startup of your app.

## **Recording navigation events**

In native apps, the native Firebase SDKs automatically track screen navigation. In React Native the navigation is often done in JavaScript and the Firebase SDK does not know how to hook-in to it, so you need to record these events yourself. The following example shows how you can use `setCurrentScreen` to track screen navigation using react-navigation. See [Screen tracking for analytics](https://reactnavigation.org/docs/screen-tracking/) in the React Navigation documentation, and where necessary substitute the tracking code with the following:

```js
Analytics.setCurrentScreen(
   currentRouteName,
   currentRouteName
);
```

## **Usage with the Expo client**

There are some differences when you use `expo-firebase-analytics` with the App Store version of the Expo client, compared to in standalone builds and the Bare workflow.

On standalone builds, in custom clients and in the Bare workflow, `expo-firebase-analytics` uses the native Firebase SDK. In the App Store version of the Expo client, it uses a JavaScript implementation of Firebase Analytics. This is because native Firebase Analytics is designed as a singleton and is tightly coupled with the default Firebase app ([related issues](https://github.com/firebase/firebase-android-sdk/issues/1264)), which doesn't work in the standard Expo client.

It proved to be impossible to get _native Firebase Analytics_ working reliably in the Expo client, [so we created a custom Firebase Analytics JavaScript implementation that can communicate with the Google Analytics back-end](https://github.com/firebase/firebase-js-sdk/issues/2644).

This allows you to test your analytics inside of the Expo client, then have the full capabilities of the native SDK in your standalone app. Some automatic events are not recorded on the Expo client, but you can still record events using `logEvent` and [use all the functions of the API](https://docs.expo.io/versions/latest/sdk/firebase-analytics/?redirected).

In order for the JavaScript implementation to work, don't forget to add the firebase web configuration to your `app.json` as mentioned above.

> _The `measurementId` field in the firebase-config is **required**. If you don't see it then you might need to [upgrade your Firebase project to the latest version of Google Analytics](https://firebase.googleblog.com/2019/07/firebase-google-analytics-upgrade.html)._

## **Why not just include `react-native-firebase` ?**

A common question that we get a lot is why `react-native-firebase` isn't included in the Expo client. If it were technically feasible for us to do that, we'd like to - but there are factors that prevent us from doing so.

One of the problems is that some parts of the native Firebase SDK are written for single-app environments and are tightly coupled with other services. This makes running the native Firebase SDK in the multi-app Expo client challenging and, in some cases like Analytics, even impossible. Other Firebase services (like Dynamic Links and some Auth providers) require that URL schemes are defined within the app in order to work.

Another issue for us is that `react-native-firebase` doesn't support web or plan to. It's important for us that packages included in the Expo SDK either provide functional parity on web or, if not possible, then a reasonable fallback.

Lastly, we need to minimize dependencies on external services in packages included in the Expo client that we ship to the stores. The core of the Expo SDK will be free of third-party service dependencies in the long run, and those libraries will instead be available to developers through our upcoming build service. This is still evolving, and we'll share more in the future.

We are looking forward to bringing as much of the Firebase functionality to our users as possible. If you have Firebase-related feature requests, feel free to add or upvote them in our [feature request tracker](https://expo.canny.io/feature-requests).

# **Resources**

* [`expo-firebase-analytics`](https://docs.expo.io/versions/latest/sdk/firebase-analytics/)
* [`expo-firebase-core`](https://docs.expo.io/versions/latest/sdk/firebase-core/)
* [Setup Native Firebase with Expo](https://docs.expo.io/versions/latest/guides/setup-native-firebase/)