DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Firebase Remote Config Complete Guide — A/B Testing/Feature Flags/Compose Integration

What You'll Learn

This article explains Firebase Remote Config (real-time updates, feature flags, A/B testing, Compose integration).


Setup

// build.gradle.kts
dependencies {
    implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
    implementation("com.google.firebase:firebase-config-ktx")
}
Enter fullscreen mode Exit fullscreen mode

Setting Default Values

<!-- res/xml/remote_config_defaults.xml -->
<?xml version="1.0" encoding="utf-8"?>
<defaultsMap>
    <entry>
        <key>feature_new_ui</key>
        <value>false</value>
    </entry>
    <entry>
        <key>welcome_message</key>
        <value>Welcome!</value>
    </entry>
    <entry>
        <key>max_items</key>
        <value>20</value>
    </entry>
</defaultsMap>
Enter fullscreen mode Exit fullscreen mode

Repository Implementation

class RemoteConfigRepository @Inject constructor() {
    private val remoteConfig = Firebase.remoteConfig.apply {
        setConfigSettingsAsync(remoteConfigSettings {
            minimumFetchIntervalInSeconds = if (BuildConfig.DEBUG) 0 else 3600
        })
        setDefaultsAsync(R.xml.remote_config_defaults)
    }

    private val _configUpdates = MutableSharedFlow<Unit>(replay = 1)

    init {
        remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {
            override fun onUpdate(configUpdate: ConfigUpdate) {
                remoteConfig.activate().addOnCompleteListener {
                    _configUpdates.tryEmit(Unit)
                }
            }
            override fun onError(error: FirebaseRemoteConfigException) {
                Log.e("RemoteConfig", "Update error", error)
            }
        })
        fetchAndActivate()
    }

    private fun fetchAndActivate() {
        remoteConfig.fetchAndActivate()
    }

    fun getBoolean(key: String): Boolean = remoteConfig.getBoolean(key)
    fun getString(key: String): String = remoteConfig.getString(key)
    fun getLong(key: String): Long = remoteConfig.getLong(key)

    val updates: SharedFlow<Unit> = _configUpdates
}
Enter fullscreen mode Exit fullscreen mode

Feature Flags

@HiltViewModel
class MainViewModel @Inject constructor(
    private val remoteConfig: RemoteConfigRepository
) : ViewModel() {

    val isNewUiEnabled: StateFlow<Boolean> = remoteConfig.updates
        .map { remoteConfig.getBoolean("feature_new_ui") }
        .stateIn(viewModelScope, SharingStarted.Eagerly, remoteConfig.getBoolean("feature_new_ui"))

    val welcomeMessage: StateFlow<String> = remoteConfig.updates
        .map { remoteConfig.getString("welcome_message") }
        .stateIn(viewModelScope, SharingStarted.Eagerly, remoteConfig.getString("welcome_message"))
}
Enter fullscreen mode Exit fullscreen mode

Compose Screen

@Composable
fun HomeScreen(viewModel: MainViewModel = hiltViewModel()) {
    val isNewUi by viewModel.isNewUiEnabled.collectAsStateWithLifecycle()
    val welcomeMessage by viewModel.welcomeMessage.collectAsStateWithLifecycle()

    Column(Modifier.padding(16.dp)) {
        Text(welcomeMessage, style = MaterialTheme.typography.headlineMedium)
        Spacer(Modifier.height(16.dp))

        if (isNewUi) {
            NewFeatureCard()
        } else {
            LegacyContent()
        }
    }
}

@Composable
fun NewFeatureCard() {
    Card(Modifier.fillMaxWidth()) {
        Column(Modifier.padding(16.dp)) {
            Text("New Feature", style = MaterialTheme.typography.titleMedium)
            Text("This new UI is enabled via Remote Config")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Summary

Feature Implementation
Initialization Firebase.remoteConfig
Default values setDefaultsAsync()
Real-time addOnConfigUpdateListener
Feature flags getBoolean("key")
A/B testing Firebase Console configuration
  • Use fetchAndActivate() to get latest values
  • ConfigUpdateListener reflects changes in real-time
  • Default values XML works offline
  • Set up A/B testing in Firebase Console

8 production-ready Android app templates (Firebase integrated) are available.

Browse templatesGumroad

Related articles:

  • Firebase Auth
  • Firebase Firestore
  • Firebase Messaging

Ready-Made Android App Templates

8 production-ready Android app templates with Jetpack Compose, MVVM, Hilt, and Material 3.

Browse templatesGumroad

Top comments (0)