The Remote config magic

Ayush Shakya
AndroidPub
Published in
7 min readAug 6, 2019
Photo by fotografierende from Pexels

Imagine this. Its the start of December and your client has requested a feature that presents a special offer to users of your app a week before and after New Years. After many team meetings, a consensus about the task deadline has been reached. Being the careful developer you are, you get the code ready, optimized and tested through and through. But sometimes, there are certain external forces that even the most meticulous developers can’t control and this story isn’t an exception. The design is on point and there seem to be no crashes, so what happened?. A management blunder on the client’s side has caused the New Years offer interval to shrink from a week to 5 days before and after. By the time this news falls upon your ears, the build has been uploaded and is ready to reveal the offer prematurely a week before the New Year.

The situation has turned dire and the clock is ticking. What will you do? You might be tempted to fix the code to reflect the new offer interval, test and optimize and send it to the store by working tirelessly before the inexorable deadline. That’s the old way. What if I told you there’s a better way?

DISCLAIMER: To get through the concepts described in this article will require a basic familiarity with Firebase. If you are going to code while reading through this article I would also recommend the built in Firebase Assistant in the recent versions of Android Studio(latest while writing this article : 3.4.2 stable channel)

Getting Remote Config to work for you

First, lets get the setup out of the way. Open up the Assistant tab in right tool buttons bar.

Tools -> Firebase -> Assistant -> Remote Config

Follow up with the remote config link and execute the initialization steps which is the firebase connection and injection of the remote config dependencies.

With the first two steps of our journey complete, lets move on to the creation of the xml file used as a default key store. Stored in the usual app/res/xml folder, this user declared xml file keeps all the default values which will be used in cases where the values are not overriden by the corresponding values sent over from the remote config service. A rudimental example of the xml schema is shown below

If however, this xml file is not present, static values corresponding to the data type are used( such as 0 for int and false for boolean)

After ensuring all the default values for missing configuration settings are handled, lets setup the handler for the fetch result of the remote config service

remote config service barebones code

As you can see the handler for the service is fairly straightforward with the standard initialization of the FirebaseRemoteConfig object and attaching the onCompleteListener. Additionally, the FirebaseRemoteConfig object is also used to setup the defaults xml using the method:

mFirebaseRemoteConfig.setDefaults(R.xml.defaults)

Now, there are two new things to note in the preceding code snippet.

First, the fetch() call. This method calls upon the config service to send the latest configs.

Another variant of this call is

fetch(long minimumFetchIntervalInSecond)

which contains the optional parameter minimumFetchIntervalInSecond which denotes the max amount of time after which the configs will be delivered from the service rather than the cached version created by the FirebaseRemoteConfig object.

The default minimumFetchIntervalInSecond time is 12 hours.

Second and the last thing to note here is the activate call. The success of the fetch call cannot be interpreted as persisting the latest configs. These configs are only persisted asynchronously after the activate call.

fetchAndActivate() is a amalgamation of the aforementioned fetch and activate calls which asynchronously fetches the configs from the server and activates them if the default minimumFetchIntervalInSeconds is crossed.

Now that the latest configs have been fetched and activated, the values can be used using the get() method in the FirebaseRemoteConfig object. Please note that the key used in the get() must match up with key defined in the remote config cloud service.

Speaking of the cloud service, lets hop on over to the firebase console to finally experience the magic of the Remote config api. Presenting a basic interface for adding key/value pairs or “parameters” which represent the configs to be sent over during the fetch() call, it also allows us to define “conditions” which help us to fine tune the parameters and the fetch() call response as a upshot. Various metrics can be used and combined to create conditions. Some of which include :

  • Platform
  • Region
  • data/time of fetch request amongst others…
Condition creator template

As we can see from the screenshot, we can stack multiple metrics to control the condition state itself. This condition in particular may target Android users in the united states and south korea before the given time and cause a configuration change.

Following this procedure, multiple custom conditions can be created that can apply to any number of parameters behaving like a if-else ladder. Lets take a example of three custom conditions as shown below :

Conditions ordered in decreasing order of priority

After these conditions are added to a parameter, their result dictates the value of the parameter.

A sample parameter, all the conditions attached to it and the default value if all the conditions fail.

Order of the conditions is of significance here as the parameter value depends on the value returned by the first condition that has been satisfied. In this case, if “condition_1” (which is simply a check if the firebase project is running on Android) is satisfied, the value returned by it (true) is the value of the parameter “event_message_display”. If however, the condition ordering was changed and now “condition_2” became the first condition and it was satisfied(the device language is English), then consequently, parameter “event_message_display” would return false.

Thus, like a if-else ladder, if the first if clause is satisfied, then all following if clauses are ignored, and if none of the clauses are satisfied, the default value is used.

Remote Config is your friend

Now that all the technical stuff is out of the way, lets talk purpose. Why is Remote config attractive? Most of its strength stems from its power to introduce new attribute values into the app without exposing the app user to the drudgery of updating the app. Lets take a simple example of a font issue that your user base has been complaining about. A small piece of text used to explain the purpose of a action was found to be too small and flew past the radar of some of your users. Usually, the fix involves changing the font size and color and pushing the updates to the store asap. But lets see how firebase remote config can help. Adding a font size and color parameter to the parameter list in remote config will allow us update the values and the next time the app fetches the new configs the new font sizes and colors will be updated. Of course, this will only work out if you have previously setup the Remote Config SDK in your app.

From bug fixing lets move on to event handling. Usually to improve user engagement in our apps, it would be nice if we could provide temporary promotional content during special events such as festivals and holidays. Once again remote configs can help us deliver this feature to our user base faster by avoiding app updates and simply hiding a feature before and after any special event and only enabling it during the duration of the event.(Remember the Date/Time metric in the parameter conditions 😋)

Finally, saving the juiciest for the last, remote configs also have a hand in A/B testing.

A/B tests always boil down to showing different variations (variant A and variant B) and using statistical analysis to determine which variant is more successful and therefore more viable.

In the case of app developers, we may want to show our users two variants of an app screen with different design elements and determine which screen elicited more positive reviews from the users. Remote config can enable this by separating a user base through random percentile targeting and showing the different screens to different users.

Hope you had a great time. If you would like more from me, don’t be afraid to give me some of that sweet applause. Cheers! 🍻

--

--

Ayush Shakya
AndroidPub

Blockchain Enthusiast / All things Android, Kotlin and Flutter