Firebase Analytics on React Native

Setting it up in 30 easy steps

Romulo Carvalho
8 min readAug 31, 2018
Resultado de imagem para meme react native

To keep it short, we're building a React Native iOS app (harder than Android) on a macOS computer previously installed with Xcode v9.4.1, cocoapods v1.5.3 via Homebrew and node.js v8.11.4 bundled with npm v5.6.0 via nvm. Instead of calling the OS-specific native Firebase SDK methods directly we'll wrap it up with react-native-firebase v5 as a platform-agnostic interface layer.

Let’s get it on, Marvin Gaye style.

1. Install the react native cli globally along with ios-deploy

npm i react-native-cli@2.0.1 -g
npm i ios-deploy@1.9.3 -g --unsafe-perm=true

2. Initialize a vanilla react native app

react-native init <project-name>

3. Enforce strict react versioning on package.json

npm i react@16.4.1 --save-exact
npm i react-native@0.56.0 --save-exact

The react-native-firebase wrapper we'll be using is very sensitive to package versions so be mindful to their compatibility chart or the platform-specific Firebase SDKs might not be integrated correctly.

4. Build the iOS app and run it through the default simulator

react-native run-ios --configuration Debug

Fire it up and grab a coffee as it might take a while. If everything goes smoothly after all build tasks finish you should see a screen like this:

5. Create a new Firebase project and sell your app soul to Google

Go to the Firebase Console and add a new project:

6. Add an iOS app to the Firebase project

7. Download the GoogleService-info.plist file

8. Move the .plist file within the xcodeproj on the ios subdirectory

Yes, you have to do it on Xcode.

9. Prepare your AppDelegate.m file on Xcode to integrate Firebase

Add the following two lines:

  • #import <Firebase.h> to the top of the file
  • [FIRApp configure]; at the beginning of didFinishLaunchingWithOptions

10. Initialize a podfile on the ios subdirectory

pod init; nano Podfile

Some observations here:

  • Don't forget to comment out the platform line on the top
  • Specify a proper compatible version for the Firebase/Core SDK
  • Add the pod GoogleIDFASupport if the app is expected to serve ads

11. Install pods

pod update && pod cache clean --all && pod install

12. Force a hard clean-up

watchman watch-del-all
rm -rf ~/<project-folder>/node_modules
rm -rf /tmp/metro-bundler-cache-*
rm -rf /tmp/haste-map-react-native-packager-*
npm cache clean --force && npm install
npm start -- --reset-cache

This step might be required multiple times before deploying, more info here:
https://github.com/facebook/react-native/issues/4968

13. Install and link a specific version of react-native-firebase

npm i react-native-firebase@5.0.0-rc1 --save-exact
react-native link react-native-firebase

P.s. at the time of writing this article react-native-firebase v5 wasn't available so the rc1 above was the only package version supporting react-native v0.56

14. Fix the Xcode build options

Open the .xcworkspace file on the project folder and go to Product > Scheme > Edit Scheme. Make sure that React is the top target under the Build tab and that Shared is checked

15. Enable the Firebase debug mode

Still under Product > Scheme > Edit Scheme add -FIRDebugEnabled as an argument passed on launch

16. Update the bundle identifier and make sure the app is signed

The iOS bundle ID here must match precisely the one on the Firebase console

17. Fix the node path under build phases on Xcode

Change the shell from /bin/sh to /bin/bash and change the first line of the "Bundle React Native code and images" script from export NODE_BINARY=node to export NODE_BINARY=$(which node)

P.s. this step is only necessary if you're running node from a non-standard location, such as for nvm users

18. Rebuild the debug app and run it again but now with Firebase

react-native run-ios --configuration Debug

19. View live automatic events on the Firebase Analytics DebugView

Attention: if the app is running with -FIRDebugEnabled it shouldn't take more than a few seconds for events to start appearing on the DebugView.

20. Deploy a release version to an actual iPhone just for fun

Run the script below replacing <device> with the device name as defined on iOS on Settings > About > Name, usually something like "DUDE's iPhone"

react-native run-ios --configuration Release --udid $(react-native run-ios --device "<device>" | grep 'Udid: ' | awk '{print $NF}')

It might take a while to run the first Release build so grab more coffee 👆

21. Upgrade the Firebase project to the "pay as you go" Blaze plan

This tier is necessary in order to be able to extend the project all over GCP

22. Enable the Google BigQuery integration on Project Settings

23. View event data on Google BigQuery after 6 to 24 hours

A day goes by and then a dataset containing event tables partitioned by date will be visible on bigquery.cloud.google.com/table/<table-name> and the table name is defined according to the syntax below.

Table names with events up to previous day (after overnight data runs):

<project-name>:analytics_<project-id>.events_<date>

Volatile tables holding same-day events (as close to real time as the SDK and GCP allows but timing and chronological order is not guaranteed):

<project-name>:analytics_<project-id>.events_intraday_<date>

The params above, defining the table names, should be replaced as follows:

  • <project-name> the full name of the respective Firebase project
  • <project-id> the Firebase Project ID found on Project Settings
  • <date> the desired date in yyyymmdd format

24. Register User Properties

Firebase allows up to 25 different Analytics User Properties per project. They're used to identify static or slow-changing attributes of your users, enabling user base segmentation/filtering throughout the Google ecosystem. They're defined as key-value pairs, with both being case sensitive strings of up to 36 characters.

More details here:

P.s. never include as User Properties personally identifiable fields such as names, social security numbers, or email addresses, even in hashed form!

Warning: as of August 2018 there seems to be no way to delete user properties from a project. Renaming is also not possible as the edit feature only allows changes to the descriptions.

25. Register Conversion Events

Conversion events are uploaded (flushed) immediately by the SDK as soon as they happen in order to make them actionable more quickly. Up to 15 events per project may be designated as conversions, in addition to the three default ones (first_open, in_app_purchase, and ecommerce_purchase).

More about conversions:

26. Register custom event parameters on Firebase

Up to 25 custom parameters might be bundled within any custom event payload (automatic events don't receive params, only user props). However, we're limited to registering up to 50 custom event parameters per project (40 numeric and 10 textual).

Some event params such as group_id and score are recommended here:

https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Param

For more details:

https://support.google.com/firebase/answer/7397304?ref_topic=6317489

27. Identify user, current screen and then log custom events

Edit the App.js file on the project root adding the Firebase header and a constructor for the default class App extends Component so that we identify the user, set the current screen name and fire a custom recommended event called app_open.

import firebase from 'react-native-firebase';
let Analytics = firebase.analytics();
export default class App extends Component {
constructor() {
super();
Analytics.setAnalyticsCollectionEnabled(true);
Analytics.setUserId(<userId>);
Analytics.setUserProperty(<propKey1>, <propValue1>)
Analytics.setUserProperty(<propKey2>, <propValue2>)
Analytics.setCurrentScreen(<screenName>, <screenComponent>);
Analytics.logEvent(<eventName>, {
<paramKey1>: <paramValue1>,
<paramKey2>: <paramValue2>
});
}
}

28. Run SQL queries

If you feel like doing it then go to the Google BQ console and try some simple queries such as:

  • How many events have we had yesterday?
select count(*)
from [oaksteps:analytics_183341603.events_20180830]
  • How many active users today?
select count(distinct user_id)
from [oaksteps:analytics_183341603.events_intraday_20180831]

29. Export event data to Google Cloud Storage

Event data stored on Google BigQuery can be exported in JSON and AVRO formats to GCS and from there you can pick it up and run custom scripts.

30. Quickly iterate over json event data using jq

jq is a super cool CLI tool to analyze data in JSON format. Installation is as simple as brew install jq. We can pipe the contents of the newline delimited json file created on the previous step into jq and pick only a few fields from the first event that happened today:

jq -s '
sort_by(.event_timestamp) | .[0] | {
what: .event_name,
when: .event_timestamp,
where: .geo.city
}
' < intraday_20180831.json
🐼

--

--