Firebase Analytics on React Native
Setting it up in 30 easy steps
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 ofdidFinishLaunchingWithOptions
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:
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