Mastering Feature Flags
Best Practices and Implementation with
Firebase Remote Config
Domen Lanišnik
Android Engineer, Lyft
Slide 2
Slide 2 text
Agenda
● Basics
● Benefits and drawbacks
● Best practices
● Advanced uses
● Getting started with Firebase Remote Config
● Summary
Slide 3
Slide 3 text
What is a Feature Flag
● Simple boolean variable
● Control remotely whether a feature is enabled
● No need to rebuild and re-release the app
Feature Flag Turned OFF Feature Flag Turned ON
Slide 4
Slide 4 text
What is a Feature Flag
if (isFeatureEnabled("shareFeatureEnabled")) {
// show Share button
}
if (isFeatureEnabled("useNewComposeScreen")) {
// open new Compose based screen
} else {
// open old View based screen
}
Slide 5
Slide 5 text
Why Use Feature Flags
● Protect against critical bugs or crashes
● Decouple from the release process
● Control which users get the feature
● Avoid long-lived feature branches
● Support one-time features
● Run A/B experiments
Slide 6
Slide 6 text
What to Watch Out For
● Overusing feature flags (complexity)
● Dependant feature flags
● Increased testing difficulty
● Stale feature flags (tech debt)
Slide 7
Slide 7 text
Best Practices
● Put new features under feature flags and ship early
● Have a clear naming convention
● Define ownership
● Perform regular reviews for stale flags
● Avoid dependent flags
Slide 8
Slide 8 text
Different Types of Feature Flags
● Int, String, Double, Lists, Json, …
● Allows for different configurations
● Enables experimenting with different values
Slide 9
Slide 9 text
Kill Switches
● Used for critical paths
● Refreshed often
● Disable an important feature in case of an issue
● Should not be same as the main feature flag
Slide 10
Slide 10 text
A/B Testing
● Divide the user base into two groups
● Gather analytics and metrics
● Decide whether to ship the new feature
Slide 11
Slide 11 text
How to Start Using Feature Flags
● Implement your own feature management service
● Use existing open-source libraries
● Use a third-party feature management service
Slide 12
Slide 12 text
Firebase Remote Config
● Cloud service for changing behavior and appearance of
apps
● Third-party feature management service
● Offers everything out-of-the-box
● Update values through console or backend APIs
● Android, iOS, Flutter, Web, and Backend
Slide 13
Slide 13 text
Implementation Steps
1. Set up (new) Firebase Project
2. Integrate Firebase SDKs into your app
3. Configure the Remote Config object
4. Fetch and activate values
5. Read values from Remote Config backend
6. Listen for updates
Slide 14
Slide 14 text
1. Set up a new Firebase Project
Slide 15
Slide 15 text
1. Set up a new Firebase Project
Slide 16
Slide 16 text
1. Set up a new Firebase Project
Slide 17
Slide 17 text
1. Set up a new Firebase Project
Slide 18
Slide 18 text
2. Integrate the SDK
Slide 19
Slide 19 text
2. Integrate the SDK
Slide 20
Slide 20 text
2. Integrate the SDK
Slide 21
Slide 21 text
2. Integrate the SDK
Slide 22
Slide 22 text
2. Integrate SDK
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
// Add the dependencies for the Remote Config and Analytics
libraries
implementation("com.google.firebase:firebase-config-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")
}
Slide 23
Slide 23 text
2. Integrate the SDK
Slide 24
Slide 24 text
3. Create a new Feature Flag
Slide 25
Slide 25 text
3. Create a new Feature Flag
Slide 26
Slide 26 text
3. Create a new Feature Flag
Slide 27
Slide 27 text
3. Create a new Feature Flag
Slide 28
Slide 28 text
4. Initialize Remote Config
class FeatureChecker {
private val remoteConfig = FirebaseRemoteConfig.getInstance()
init {
val configSettings = remoteConfigSettings {
minimumFetchIntervalInSeconds = 3600L
}
remoteConfig.setConfigSettingsAsync(configSettings)
}
}
Slide 29
Slide 29 text
5. Set Default Values
remoteConfig.setDefaultsAsync(
mapOf(
"detailsScreenEnabled" to false,
"descriptionMaxLineCount" to 2L,
"detailsNavigation" to "BOTTOM_SHEET"
)
)
Slide 30
Slide 30 text
6. Fetch Remote Values
suspend fun fetchFeaturesConfig(): Boolean {
return remoteConfig.fetchAndActivate().await()
}
● Blocking during app startup (splash screen)
● Async and update immediately
● Async and use new values next time
Slide 31
Slide 31 text
7. Read Values
fun isFeatureEnabled(featureFlagName: String): Boolean {
return remoteConfig.getBoolean(featureFlagName)
}
fun getLongValue(key: String): Long {
return remoteConfig.getLong(key)
}
Slide 32
Slide 32 text
6. Read Values
class ViewModel(private val featureChecker: FeatureChecker) : ViewModel() {
private val _detailsScreenEnabled: MutableStateFlow =
MutableStateFlow(false)
val detailsScreenEnabled: StateFlow = _detailsScreenEnabled
init {
viewModelScope.launch {
_detailsScreenEnabled.update {
featureChecker.isFeatureEnabled("detailsScreenEnabled")
}
}
}
}
Slide 33
Slide 33 text
6. Using it in Compose with a
ViewModel
val detailScreenEnabled = viewModel.detailsScreenEnabled
.collectAsState()
.value
if (detailsButtonEnabled) {
IconButton(
onClick = {},
) {
Icon(
Icons.Default.ArrowForward,
contentDescription = "Open details"
)
}
}
Slide 34
Slide 34 text
8. Observe Updates in Real-Time
● Receive new values as soon
as published
● Opens HTTP connection to
Remote Config backend
Source: https://firebase.google.com/docs/remote-config/real-time?platform=android
Slide 35
Slide 35 text
8. Observe Updates in Real-Time
suspend fun observeFeatureConfigChanges() = callbackFlow {
firebaseRemoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {
override fun onUpdate(configUpdate: ConfigUpdate) {
firebaseRemoteConfig.activate().addOnCompleteListener {
trySend(configUpdate.updatedKeys)
}
}
override fun onError(error: FirebaseRemoteConfigException) {
close(error.cause)
}
})
awaitClose { }
}
Additional Capabilities
● A/B experiments
○ Used with Google Analytics
● Personalization
○ Uses ML to deliver custom experience to each user
○ Automatically achieve maximum conversion
○ Can be useful for showing ads, adjusting difficulty level in a game, …
Slide 43
Slide 43 text
Setting up an A/B Experiment
● how to set up
● how to target specific users
● code examples
Slide 44
Slide 44 text
No content
Slide 45
Slide 45 text
No content
Slide 46
Slide 46 text
No content
Slide 47
Slide 47 text
Firebase Remote Config Limitations
● Free to use for unlimited daily active users
● Maximum 2000 parameters
● Parameter keys can be up to 256 characters long
● Maximum 500 conditions
● Throttling (default is 12 hours)
● Up to 300 total A/B experiments (max 24 running)
Slide 48
Slide 48 text
Summary
● Feature flags are a powerful tool
● Make building and releasing mobile apps both safer and
faster
● Benefits outweigh the drawbacks
● Stick to the best practices
● Easy to get started with Firebase Remote Config