Home Android & Kotlin Books Real-World Android by Tutorials

19
Firebase Integration Written by Subhrajyoti Sen

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Building and releasing an app is quite a feat, but you soon realize that it’s just the first step of the process. You need to monitor how your app performs for different users and how your users interact with the app, among other factors, so you can offer the best possible experience.

Traditionally, you’d need different tools for each of these tasks, and building and integrating everything would be tedious. Google addressed those problems by introducing Firebase, a complete suite of services that can help you build your app faster, monitor it in the real world and better engage your users.

In this section, you’ll learn how to use:

  1. The Firebase Console to set up Firebase for your project.
  2. Crashlytics to detect and understand app crashes.
  3. Remote Config to add dynamic content to your app.
  4. Test Lab to perform different tests across a wide range of devices.

You’ll start at the beginning: getting Firebase ready to use.

Setting up Firebase

To set up Firebase, you first need to create a new project at https://console.firebase.google.com. Log in using a Google Account and you’ll see the Firebase Console. Firebase will prompt you to create a new project, as shown below:

Figure 19.1 — Creating a Firebase Project
Figure 19.1 — Creating a Firebase Project

Creating a Firebase project

Clicking Create a project will bring you to the Create a project page. You’ll see a prompt to provide a project name, as shown below. Enter PetSave.

Figure 19.2 — Insert Firebase Project Name
Qudelu 72.5 — Ejyabg Pafuzagu Yzoyayg Qeyi

Figure 19.3 — Google Analytics Configuration
Wojuhu 65.1 — Saujhu Ocanqyoff Niqgequcaqoan

Registering an app

Now that you’ve created your project, you’ll see an option to add Firebase to your app, as shown below:

Figure 19.4 — Adding Firebase to Your App
Fogeti 24.4 — Ebbeyg Talinuzo yo Miiz Edv

Figure 19.5 — Register Your App
Geyopi 51.0 — Bewulsev Xaat Iqx

classpath 'com.google.gms:google-services:4.3.4'
apply plugin: 'com.google.gms.google-services'
implementation platform('com.google.firebase:firebase-bom:26.2.0')

Crashlytics

App crashes are among the things developers dread the most. Not only do they prevent the users from using one of the app’s features, but they also create a negative impression. Having a high crash rate leads to lower ratings on the Play Store, more uninstalls and revenue loss.

Setting up Crashlytics

Setting up Crashlytics is straightforward. Select Crashlytics from the left navigation bar on the Firebase Console and you’ll see a page like the one below:

Figure 19.6 — Enabling Crashlytics
Susuxu 41.5 — Eweysexy Tbulxzvvozr

classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'
apply plugin: 'com.google.firebase.crashlytics'
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'

Testing and debugging

To test your Crashlytics setup, you need to cause an intentional crash. Do this by opening AnimalsNearYouFragment.kt and adding the following code to onViewCreated:

throw NullPointerException()
Figure 19.7 — Simulating a Crash
Tisele 62.2 — Takozuposh a Fwiwj

Non-fatal exceptions

You can also use Firebase to log non-fatal exceptions. In most cases, you log such exceptions locally. While this approach works during development, local logs are useless when the app is on a user’s device. Instead, you’ll log them in Crashlytics.

try {
  throw NullPointerException()
} catch (exception: Exception) {
  FirebaseCrashlytics.getInstance().recordException(exception)
}
Figure 19.8 — Filtering a Non-Fatal Exception With Crashlytics
Geveca 77.7 — Harsuguvh a Som-Xuyix Epsahyeab Sawv Fvurdmsmoyb

Using Crashlytics with Proguard

You probably enabled Proguard on your release builds before publishing it to the Play Store. In that case, the logs uploaded to Firebase will be obfuscated and, therefore, difficult to read.

debug {
  minifyEnabled true
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
-keepattributes SourceFile,LineNumberTable

Uploading the mapping file

The Crashlytics Gradle plugin can automatically detect if code is obfuscated and upload the mapping file to the Crashlytics servers accordingly. Though this process is handy, it slows down build times.

firebaseCrashlytics {
  mappingFileUploadEnabled false
}
debug {
  minifyEnabled true
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  firebaseCrashlytics {
    mappingFileUploadEnabled false
  }
}

Remote Config

As an app developer, you’ll run into situations where you need to change small details in your app from time to time. Making a new release for a small change is cumbersome, especially since Play Store can take anywhere from a few hours to a few days to update. For these cases, Firebase provides Remote Config.

Setting up Remote Config

You can treat Remote Config as a read-only entity that’s unaware of the implementation details of the app. You can also treat it as a source of key-value pairs.

implementation platform('com.google.firebase:firebase-bom:26.1.1')
implementation 'com.google.firebase:firebase-config-ktx'
object RemoteConfigUtil {

  private val DEFAULTS: HashMap<String, Any> = hashMapOf()

  private lateinit var remoteConfig: FirebaseRemoteConfig

  fun init(debug: Boolean = false) {
    remoteConfig = getFirebaseRemoteConfig(debug)
  }

  private fun getFirebaseRemoteConfig(debug: Boolean): FirebaseRemoteConfig {

    val remoteConfig = Firebase.remoteConfig

    val configSettings = remoteConfigSettings {
      if (debug) {
        minimumFetchIntervalInSeconds = 0
      } else {
        minimumFetchIntervalInSeconds = 60 * 60
      }
    }

    remoteConfig.setConfigSettingsAsync(configSettings)
    remoteConfig.setDefaultsAsync(DEFAULTS)
    remoteConfig.fetchAndActivate()

    return remoteConfig
  }
}
implementation project(":remoteconfig")
RemoteConfigUtil.init(BuildConfig.DEBUG)

Adding a config

Open fragment_secrets.xml. You’ll notice an android:src attribute specifying the image to display. Remove the attribute and add an id to the ImageView, as follows:

<ImageView
  android:id="@+id/secret_image"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />
private const val SECRET_IMAGE_URL = "secret_image_url"
private val DEFAULTS: HashMap<String, Any> =
  hashMapOf(
      SECRET_IMAGE_URL to "https://images.pexels.com/photos/1108099/pexels-photo-1108099.jpeg"
  )
fun getSecretImageUrl() = remoteConfig.getString(SECRET_IMAGE_URL)

Using a dynamic value to update the UI

The only thing left to do on the app side is updating SecretFragment.kt to use the updated value and setting the image in the ImageView.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  super.onViewCreated(view, savedInstanceState)

  binding.secretImage.setImage(RemoteConfigUtil.getSecretImageUrl())
}
Figure 19.9 — Testing Remote Config
Motuka 78.0 — Riyjiqr Jacova Xucnan

Updating the Remote Config value

To update the value of any Remote Config key, open the Firebase Console and select the Remote Config option from the left navigation bar. It’s in the Engagement section.

Figure 19.10 — Add a New Parameter to Remote Config
Pacino 16.33 — Ubb a Sik Fevepadez hi Gehizu Hilgej

Figure 19.11 — Unpublish Changes
Sawifo 52.68 — Isxuphirr Rjegzep

Figure 19.12 — Testing Configuration Changes With Remote Config
Mudafo 78.20 — Hulsovc Bigjanuvoraus Crijyur Gekj Kahofi Kemwiz

Firebase Test Lab

Android is a highly fragmented operating system. It runs on thousands of different device variants, and each manufacturer makes its own changes. The way an SDK works on a Pixel device can differ from how it works on a Xiaomi device. Additionally, Android brings out a new version each year, and with each new release, many APIs change. Given all these variations, you’ll need to test your app on devices with different Android versions and from different manufacturers.

Running your first test

To run your first test on Test Lab, visit the Firebase Console and select Test Lab from the navigation bar on the left.

Figure 19.13 — Getting Started With Test Lab
Dusoqi 33.60 — Neybayf Rdottab Tukw Bifk Giq

Figure 19.14 — Test Lab Default Test Matrix
Qubovu 66.12 — Nact Keq Rudeixk Riqp Tovqep

Creating a Robo test preset

A test preset is like a template that you can use to run your tests instead of configuring the options every time. A preset consists of the following:

Figure 19.15 — Test Lab New Preset
Mipayu 88.38 — Xihw Voz Ceh Dquvaf

Figure 19.16 — Customize Your Test Matrix
Muface 55.02 — Diggebuzi Joej Meyz Wegkup

Creating an instrumentation test preset

An instrumentation test preset differs from a Robo test preset only in the Additional options section. To create an instrumentation test preset, select Instrumentation test as the Test type and expand Additional options. There are three options in this category:

Running a new test

To run a new test, visit the Test Lab dashboard and click Run a test. Select the type of test you want from the drop-down menu.

Figure 19.17 — Robo Script Configuration
Jebovo 32.34 — Kudo Tqpiyz Gavnudovokiez

./gradlew assembleAndroidTest

Key points

  • Crashlytics is easy to set up and can play a big part in keeping your app’s crash rate under control.
  • Use Crashlytics to log non-fatal exceptions.
  • Use Remote Config to introduce dynamic content and behavior in your app.
  • Evaluate when it’s appropriate to activate the Remote Config values to provide a good user experience.
  • Test Lab lets you run both Robo and Instrumentation tests on a wide range of devices.
  • Use Orchestration and Sharding to get faster and more reliable test results.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2021 Razeware LLC

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.