Remote Config Feature Flagging: A Full Walkthrough

Andrea Wu
Firebase Developers
7 min readJun 17, 2021

--

As a developer who works on the Firebase console, I not only build and test a feature before release, I also launch the feature using progressive rollouts to make sure everything is working as intended before exposing it to our full user base. In fact, this is a common practice that I follow all the time!

When a new feature is being developed, I connect code to an internal tool specifically for feature flagging to hide unfinished work so half-baked visualizations aren’t being exposed to users. Once the new feature is ready for launch, I use the tool to first expose the feature to a small number of users, eventually exposing it to all users after gaining confidence that everything works as intended. In the event of issues arising with the initial rollout, I can easily immediately switch the flag off before too many users get affected.

Feature flagging enables testing the new feature on a small audience and provides an easy way to roll back just in case it’s buggy.

Feature flagging has been critical since the early days at Google, so we developed an internal system to support it, and it’s what I use. We knew it would be critical for our users as well though, which is why Remote Config supports it!

To backtrack a bit, what is Remote Config? At a high level, it’s a key-value store in the cloud, and apps running on end-user devices use these key-value pairs to configure desired user experiences. Here is more information on Remote Config.

While the documentation has lots of information on how to get started and using Remote Config for your desired platform, I realized there’s no detailed walkthrough for how Remote Config works from start to finish for common developer use cases, like setting up a feature flag in production, so that’s why I wanted to put together this post!

Let’s imagine that we’re working on an app, Trekker, where nature-lovers like me can find great hikes. Trekker is already loved by users for its ability to curate the best hikes in the area and display maps to follow along during a hike, but there isn’t yet a way to share that experience with friends. This will probably be a great way to unlock some additional growth: let customers review their hikes and share their reviews with friends. They’ll enjoy showing off their trips into nature, and the shared reviews will help drive more downloads of Trekker.

This sounds like an awesome feature, but any new feature comes with new risks. What if our users don’t like this feature, or worse, what if the new feature is broken and causes our app to crash? We definitely want to reduce these risks as much as possible before exposing this new feature to our loyal users, and as such, we might consider dogfooding internally as a first step to identify any major problems.

Let’s see how Remote Config can limit the exposure of this new feature just to internal users through the use of feature flagging.

Before starting development on this feature, we’ll go into Remote Config and create a parameter as this feature flag. To set it up, let’s name the feature flag review_feature_enabled and set the default value to false so the feature is hidden from customers during the development phase. We’ll add the parameter and publish the changes to make it available for consumption in Trekker.

Now that the parameter is set up, it can be used in Trekker to ensure any development done for this feature does not appear for external users. Let’s skip ahead a bit to where we’ve added a share button hidden behind the feature flag. How can our development team test the change since it’s currently hidden behind a flag?

Setting a user property can help — user properties are attributes that can be set in the app, like whether or not a user is an internal user. We can then tell Remote Config to enable behavior for users that have particular values set.

In Firebase Console’s Custom Definitions under Analytics, set a new user property called is_internal_user:

With this, we can go back to Remote Config and edit the feature flag. We’ll define a new condition called internal testers and apply it if the user property for is_internal_user is true.

For those testers, we’ll want to provide a value of true so the feature can be seen by those testers.

Now that the flag is enabled for the test account, the share button can be seen on the app, and as we, the Trekker team, continue building out the share feature, those changes can continue to be visible only to us.

Eventually, the feature is ready to be rolled out to users! Since we’re using Remote Config, we can do a percentage-based rollout: start by exposing the feature to a small portion of the user base before releasing it to all. This way, we can keep a close eye on metrics, support channels, and app store reviews to make sure that the launch is going smoothly.

To do so, we’ll define a new condition, Review feature rollout, to start the rollout and set it to apply for Trekker. Then, add a condition for user in random percentile with 5%.

This condition gets saved to our existing parameter, and the value gets set to true for that rollout. Update and publish changes, and just like that, this share feature was launched to 5% of users!

While it’s being only exposed to a small percentage of users, we can set a user property to track users who have been exposed to the feature in order to watch out for suboptimal app behavior, like crashes or slow startup time, as well as impact to other analytic events based on the fact that these users are exposed to the new feature. If we see these situations happening, this is likely an indication of a possible issue with the new feature, and rolling back the feature is probably a good next move.

To turn the feature off while a fix gets investigated, let’s go back and edit the flag by setting the rollout condition value to false. Publish that change, and the feature is easily hidden and users will no longer have to deal with the buggy state. No long nights trying to fix the bug or stressing out about getting bad app store reviews from the developer’s side either! Using Remote Config, we were able to maintain control of the released code while keeping users happy.

Some time goes by for the code fix and the new version gets shipped out to users. Now that it’s out in the wild, we can roll out the feature again. However, we don’t just want to turn that feature flag on for everyone though, because some users still have the buggy version of Trekker. Thus, we’ll use another targeting condition to limit the versions of the app for which the flag gets enabled.

In the conditions tab, edit the rollout condition by adding another criteria, version condition. The version with the bug fix is 1.2, so we’ll only turn the flag on for this or future versions of the app. After saving the condition, we go back to the parameter and change the rollout value back to true. Once these changes are published, the rollout has restarted!

As we observe usage of the feature and feel confident in rolling out to a larger audience, we can go to the conditions tab and increase the percentage, ultimately reaching 100% and completing the launch! This flag still needs to stay in place though to prevent any customers still on the bad version from receiving the buggy version of the share feature. As users continue upgrading to newer versions of the app, hopefully the flag can eventually be removed altogether after nobody is using the buggy version in order to keep our configuration clean and tidy. We should also archive the user properties used for this feature after they become obsolete as we may run out of user properties quickly if we use one per feature.

So there we have it! Using Remote Config, we were able to develop a new feature behind a feature flag, launch it to a small set of users, roll back quickly, and ensure users will only see the non-buggy version of the feature going forward!

--

--