Firebase Remote Config — Making It Work For You

Because remote is always better

tomerpacific
Better Programming

--

BecausePhoto by Rima Kruciene on Unsplash

Remote configurations are useful since they allow you to alter behavior in your application without having to release another version. One prominent example is using remote configurations to decide if a feature should be turned on or off. That way, you can gradually roll it out to production or test it to see how users react.

Usually, if you want your application to have this behavior, you would have to develop your server and its logic. But we live in an age of technology and innovation, so someone created a tool that can help minimize our development time and help us in this endeavor.

This tool is called Firebase Remote Config (surprise, surprise).

Overview

Part of the full suite of Firebase also includes Remote Config. You can access this inside your project’s Firebase console under the Release & Monitor section on the left side panel.

There are two ways in which you can define your remote configurations:

  1. Through Firebase
  2. Using a template file that is in JSON format

We will focus on the first option, as the second option is the less intuitive approach.

Inside Firebase Remote Config, you can define one or more keys that will be set in these configurations. These keys can be of the following type:

  • String
  • Number
  • Boolean
  • JSON

Each key you set has a few other settings that may be useful to you. For one thing, you can define a default value for it (i.e., false for a Boolean) or make it use a value that you set in your application. But the cool thing you can do, if you click on the Add new button on the bottom left, is to allow the value of this key to be determined by other factors:

  • Conditional Value
  • Experiment
  • Personalization

Once you are done adding a key, make sure to publish your changes so they will be deployed

Conditional value

Configure how a value will be set to a selection of users based on various conditions.

Here, you can decide on what you want to test and how. You will discover several options if you click on the “Applies if” dropdown. To illustrate the use of this feature, let’s say that you want to target iOS users in the US. To do that, in the “Applies if” dropdown, you choose Platform and then iOS. After that, you can press the and button to add a condition for Country/Region and choose United States.

Make sure to also name your condition, or otherwise, the Create condition button won’t be enabled.

Notice how the last field in defining a new condition window tells you how many users will be affected by this condition

Experiment

This option lets you change the behavior of a value in your remote configurations before taking effect on all your users.

  • In the first step, you fill in the name and description of your experiment
  • Then, you choose which application to target and how many users will be affected (percentage-wise)
  • The third step is to set up the metrics to measure this experiment. There is a primary metric and additional metrics
  • Lastly, you can decide on the number of A/B test groups for this experiment

Personalization

Last but not least is the option to tailor a specific value of your remote configurations to a user based on their own behavior.

You can define values the algorithm may supply to the user based on their behavior. These will be chosen by an objective you define (Step 2). This objective can range from the engagement time of the user to the amount of clicks they perform. In Step 3, you define a condition that will target users so that they will become personalized. Lastly, in Step 4, you add the name and description of this personalization.

Each option has much more to offer than what I have described here, so if you want to learn more, you can use one of the reference links at the bottom. Now that we understand what Remote Config is, let’s see how we can add it to our application.

Setup

Before you can do anything related to applying remote configurations, you need to make sure you add Firebase to your Android project. This has been documented here. After you have done that, follow these steps:

  1. Add the Firebase remote configuration library to your project
 implementation 'com.google.firebase:firebase-config-ktx'

There is an option to also import the Firebase Analytics module, but it is not required for remote configurations. It is used in other areas of remote configurations, such as defining a condition based on a specific event happening.

2. After syncing your project, you can access the RemoteConfig object with this command:

val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig

3. You can define how often your remote configurations will be fetched and, thus, updated. When you are still developing your application, setting this number to be relatively low is worthwhile.

val remoteConfigSettings = remoteConfigSettings {
minimumFetchIntervalInSeconds = 2000
}

If you set the minimumFetchIntervalInSeconds to be too low, Firebase will throw a FirebaseRemoteConfigFetchThrottledException

4. Set the configuration settings

remoteConfig.setConfigSettingsAsync(remoteConfigSettings)

5. You can have application default values for your remote configurations. These can be created as an XML file inside the XML directory inside the res folder. Here’s what the code looks like:

remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults)

This XML file must have an underlying element of a map to wrap all your default values. For example, let’s imagine we have defined a key in remote configurations called my_key, whose value is 1. The XML for the default values will look like this:

<?xml version="1.0" encoding="utf-8"?>
<defaultsMap>
<entry>
<key>my_key</key>
<value>1</value>
</entry>
</defaultsMap>

Remote configurations need to be fetched and activated. The fetch action fetches and stores your Remote Configurations inside the Remote Config object. The activation part is to make these values available to your application. That’s why there are two API methods:

  • fetch (and later use activate)
remoteConfig.fetch()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
//Remote Configurations fetch successfully
}
}
.addOnFailureListener { error ->
//Remote Configurations fetch failure
}


-------------------------
remoteConfig.activate()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
//Remote Configurations activation success
}
}
.addOnFailureListener { error ->
//Remote Configurations activation failure
}
  • fetchAndActivate
remoteConfig.fetchAndActivate()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
//Remote Configurations fetched and activated successfully
}
}.addOnFailureListener { error ->
//Remote Configurations fetched and activated failure
}

6. Now that our remote configurations have been fetched and activated, we can access and use them in our application. We can do so by accessing the remoteConfig object and using one of the getter methods per the type of the value we set:

val myRemoteConfigValue: String = remoteConfig.getString("my_key")

Configuration Loading Strategy

Since your application will rely on remote configurations for its operation (or parts of it), it is crucial to decide how the application will behave if it does not arrive or takes too long to receive a response. In essence, there are two ways to handle loading the remote configurations:

  1. Your application boots up and waits for the remote configurations to be activated
  2. Your application boots up and does not wait for the remote configuration to be activated. Opting instead to use the remote configurations on the second application run

There are good and bad implications for each of these methods, and it’s up to you to decide which is better suited for your application. If you choose the first option, you may add a loading screen that times out after a certain period. Or, if you choose option two, you will create a default mechanism for features in your application and how they should work when the configuration has not yet been received.

--

--