How not to leak features when using Firebase Remote Config
Remotely turning on and off features is a great concept. It adds another layer of confidence when releasing new versions of your app.
You release your new version first, make sure there were no regression, and then turn on any new features one at a time. Did something go terribly wrong with the shiny new feature? No panic, no rollbacks, no new releases. Just remotely switch it off.
One of the most popular solutions for controlling the app's behavior remotely is the Firebase Remote Config. And it delivers. It's reliable, easy to integrate, and provides a friendly UI for turning on and off features.
The way it works is by not executing the code of a new feature if the remote flag is not enabled. For instance, a feature flag might be called shiny_feature
. Firebase will fetch the enabled features usually during startup. If the shiny_feature
flag is in the enabled list, then this feature will become available to the users.
What happens though when you guard your new feature behind a flag during development? When you start sending test versions to colleagues and QA you might think it's fine to turn the feature on for the testing period, and then turn it off just before the new version is released to the public.
But this might be problematic since the clients will be fetching the list of enabled flags for that testing period. The fetching of the enabled flags is a best-effort process. If for some reason it cannot be fetched, the app will use the last version of the enabled flags list already on the device. Releasing the app immediately after turning off a feature, and you will almost definitely witness usage of the guarded features, even if you have the feature off.
So what's the solution to this problem? Just use different feature names before and after releasing a feature. An easy way to do this, instead of manually changing the flag name before the production release, is to automatically append a post-fix to the feature name to distinguish between the development and production versions.
A simple sample code would be:
fun featureName(name: String) =
"$name${if (BuildConfig.DEBUG) "_dev" else "_prod"}"
Remember to import the correct BuildConfig
of your app's module. Alternatively, use some build variants to distinguish between prod and non-prod versions.
Hopefully, you learned how to avoid any feature to accidentally be enabled on your watch :)
Happy coding!