Cannonball’s Journey from Fabric to Firebase

../../_images/cannonball-overview.png

From left to right: Sign In, Poem Creator, Your Poems, and About screens.

Overview

Cannonball is a magnetic poetry game. Choose your theme, get a bag of words, and start making poems right away!

Follow along in this guide to learn how we migrated Cannonball from Fabric to Firebase and how you can migrate your own apps.

Tip

We also migrated Cannonball for iOS. It’s open-sourced on GitHub. You can also read the tutorial to build Cannonball for iOS.

Note

Sections marked “Bonus” are specific to Cannonball. Although they’re not necessary to migrate every app from Fabric, you can use them to learn more about Firebase!

Getting Started

Prerequisites

This guide assumes that you have a Google account and that you’re able to access the Firebase Console. It also assumes you’re familiar with Git and Android Studio.

You can follow along in Cannonball’s code by downloading its source from GitHub. If you change branches to initial, you’ll be able to see how the app looked before the migration.

Creating a Firebase project

Firebase, Crashlytics’ new home, organizes apps in a similar way to Fabric. A Firebase project is similar to a Fabric organization.

When we migrated Cannonball, we created a single Firebase project to contain both the Android and iOS versions of Cannonball. We’d recommend you do the same for your cross-platform apps to take advantage of having shared Firebase features like Realtime Database. However, for apps that are completely different (e.g. ChatApp and CasinoApp), we’d recommend making different projects.

Transitions

Step 1. Remove the Fabric initialization code.

First, remove the crashlytics.properties file.

We’ll need to remove Fabric from our app-level build.gradle by doing the following:

  1. Remove the buildConfigTypes in the buildTypes section of your app/build.gradle.
  2. Remove Fabric dependencies in app/build.gradle.
  3. Remove any references to the crashlytics.properties file.
  4. Remove any import io.fabric.sdk.android.Fabric; and Fabric.with() statements from your project.

Step 2: Add Firebase to your app.

To add Firebase to your app, follow along in the Firebase Documentation under “Manually add Firebase to your app”.

Here are the code changes we’ve made to our main App.java so far:

--- _static/diffs/App_01.java
+++ _static/diffs/App_02.java
@@ -1,4 +1,4 @@
-import io.fabric.sdk.android.Fabric;
+import com.google.firebase.FirebaseApp;
 
 public class App extends Application {
     private static App singleton;
@@ -14,7 +14,7 @@
         singleton = this;
         extractAvenir();
 
-        Fabric.with(this, new Crashlytics(), new Digits(), new Twitter(authConfig), new MoPub());
+        FirebaseApp.initializeApp(this);
     }
 
     private void extractAvenir() {

Step 3: Set up Firebase Crashlytics.

To set up Firebase Crashlytics, follow along in the Firebase Documentation on Getting started with Firebase Crashlytics.

Note: In your app-level build.gradle, be sure to update your Crashlytics dependency to the latest version. Also, to get the full features of Crashlytics, include firebase-core.

Once you finish setting up Firebase Crashlytics, you can test your implementation by forcing a test crash in your app.

Step 4: Convert Fabric Answers to Google Analytics for Firebase.

Google Analytics for Firebase (often just called Analytics) provides the same powerful insights as Answers while integrating closely with the rest of the Firebase suite.

Analytics provides many predefined events that we recommend you use. Here’s a table of Answers events and their corresponding Analytics events:

Answers Event Analytics Event
logPurchase ECOMMERCE_PURCHASE
logAddToCart ADD_TO_CART
logStartCheckout BEGIN_CHECKOUT
logContentView VIEW_ITEM
logSearch SEARCH
logShare SHARE
logRating (No direct corollary)
logSignUp SIGN_UP
logLogin LOGIN
logInvite (No direct corollary) Maybe: SHARE
logLevelStart LEVEL_START
logLevelEnd LEVEL_END

To migrate your Answers code to Analytics, check the getting started guide to make sure you’ve included the necessary dependencies and startup code. If you’ve already initialized Firebase in your app, you can skip ahead to the section titled “Log Events”.

Then, change your Answers logFoo statements (where Foo is an Answers Event in the table above) to FirebaseAnalytics.logEvent using the appropriate event listed in the above table or your own custom event (use your own string instead of one of the constants available in the Firebase library).

The Analytics documentation shows parameters relevant to each predefined event, but you can always add customer parameters too. Instead of using one of the available constants, you can use any string you’d like. Then, register that parameter in the Firebase Console.

If an Analytics event is especially important to your business (such as a user spending money, or completing a critical flow in the app), you can configure it as a conversion.

Read more about how to log events (including how to attach relevant parameters) here.

Example Answers to Analytics Code

--- _static/diffs/PoemHistoryActivity_01.java
+++ _static/diffs/PoemHistoryActivity_02.java
@@ -1,6 +1,4 @@
-import com.crashlytics.android.answers.Answers;
-import com.crashlytics.android.answers.CustomEvent;
-import com.crashlytics.android.answers.ShareEvent;
+import com.google.firebase.analytics.FirebaseAnalytics;
 
 class OnShareClickListener implements View.OnClickListener {
     @Override
@@ -8,8 +6,13 @@
 
         ...
 
-        Answers.getInstance().logShare(new ShareEvent()
-                .putMethod("Twitter").putContentName("Poem").putContentType("tweet with image"));
+        Bundle bundle = new Bundle();
+        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "poem_image");
+        bundle.putString(FirebaseAnalytics.Param.METHOD, "native_share");
+        bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, this.poem.getTheme());
+        bundle.putInt("length", this.poem.getText().split("\\s+").length);
+
+        mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
 
         ...
 

Next Steps

Use Firebase Authentication

In order to provide a seamless experience on mobile and a way to carry data from one device to another, we needed to provide a way for users to log in. Originally, Cannonball used Twitter and Digits to sign in. Now, Firebase Authentication handles these login methods and can easily be extended to handle more.

In Cannonball, we decided to use Phone Number Authentication and Anonymous Authentication.

To use Firebase Authentication in your app with a custom UI, follow the guide here. If you’d like to try a pre-built UI that already handles all of Firebase Authentication’s supported login flows (including phone number authentication), check out FirebaseUI.

Convert local storage of poems to use Firebase Realtime Database

Users can keep a history of the poems they created and share their favorites. In the old version of Cannonball, the poems were stored locally, but in the updated version, Cannonball uses the Firebase Realtime Database (RTDB) to persist poems across different devices. You can even log in on an iOS device, create a poem, and have that same poem appear on an Android device!

In the process of integrating the Realtime Database, we were able to get rid of a lot of code around local persistence. If we were concerned about offline capability in our app, it only takes a single line of code to turn that on in the RTDB SDK.

Here’s what we had to do in Cannonball to use the Realtime Database:

Try other Firebase features

  • The open source FirebaseUI library contains helpful UI Bindings for the Firebase Realtime Database, as well as other Firebase services.
  • Try Firebase APIs by building projects with quickstart samples.