Implementing Force Update with Firebase Remote Config in Android Kotlin

Mert Melih Aytemur
Appcent
4 min readAug 29, 2023

--

Introduction

Keeping your mobile app’s user base up-to-date with the latest features, bug fixes, and security enhancements is crucial. However, users might not always willingly update their apps, which can lead to compatibility issues and potential security vulnerabilities.

To tackle this challenge, Firebase Remote Config comes to the rescue. In this article, we’ll explore how to leverage Firebase Remote Config to implement a forced app update mechanism in an Android app using Kotlin.

What is Firebase Remote Config?

Firebase Remote Config is a cloud-based service provided by Firebase that enables you to customize the behavior and appearance of your app without publishing app updates.

It allows you to define key-value pairs in the Firebase console, which your app can fetch remotely and apply changes accordingly. This feature becomes particularly powerful when it comes to implementing forced app updates.

Scenarios for Forced App Updates:

  1. Critical Bug Fixes: If you discover a critical bug in your app that affects its functionality or security, you might need to force users to update to the latest version that contains the fix.
  2. Mandatory Feature Rollouts: Sometimes, you might introduce new features that are essential for the app’s core functionality. To ensure a consistent user experience, you can force users to update and access those features.
  3. Security Updates: Security vulnerabilities can emerge over time. By forcing users to update, you can ensure that they are protected from potential security threats.

Implementation Steps:

Step 1: Configure Firebase Project

  1. Create a Firebase project if you haven’t already.
  2. Add your Android app to the project and follow the setup instructions to integrate Firebase into your app.

Step 2: Set Up Firebase Remote Config

  1. In the Firebase console, navigate to Remote Config and create a new parameters like “android_force_update_required”, “android_force_update_required_version”, “android_force_update_store_url”
  2. Set the parameter value to true when a forced update is required.

Step 3: Implement Remote Config in Your App

1- Add the Firebase Remote Config dependency to your app-level build.gradle file:

implementation 'com.google.firebase:firebase-config-ktx:x-y-z'

2- Initialize Firebase Remote Config in your application class or a relevant activity and fetch remote config values and check for a forced update:

Suggestion is creating ForceUpdateChecker class in here, (Dependency Injection applied via Dagger-Hilt)

class ForceUpdateChecker @Inject constructor() {
/**
* About [setDefaultsAsync]
* Provided default values for your parameters that act as fallbacks
* in case the actual remote values are not available due to network issues or if the parameters haven't been fetched yet.
* This helps ensure that your app doesn't break or behave unexpectedly if there's a delay in fetching remote configuration values.
*
* Set an interval for fetching config. (Default is 12 hours)
*
* Compare current and required versions.
* If current version is lower than required one, fetch store url and set to Force Update Data Model
* otherwise return null
*/
fun checkForceUpdateRequired(updateRequired: (result: ForceUpdateDataModel?) -> Unit) {
val remoteConfig = FirebaseRemoteConfig.getInstance()
remoteConfig.setDefaultsAsync(
mapOf(
KEY_UPDATE_REQUIRED to false,
KEY_REQUIRED_VERSION to BuildConfig.VERSION_NAME,
KEY_UPDATE_URL to "store_url"
)
).addOnCompleteListener {
remoteConfig.fetch(MINIMUM_FETCH_INTERVAL).addOnCompleteListener {
if (it.isSuccessful) {
remoteConfig.activate().addOnCompleteListener {
if (remoteConfig.getBoolean(KEY_UPDATE_REQUIRED)) {
val currentVersion = (BuildConfig.VERSION_NAME).replace(".", "").toInt()

val requiredVersion =
remoteConfig.getString(KEY_REQUIRED_VERSION).replace(".", "")
.toInt()

if (currentVersion < requiredVersion) {
updateRequired.invoke(
UpdateRequiredModel(
updateUrl = remoteConfig.getString(KEY_UPDATE_URL)
)
)
} else {
updateRequired.invoke(null)
}
}
}
} else {
updateRequired.invoke(null)
}
}
}
}

companion object {
const val KEY_UPDATE_REQUIRED = "android_force_update_required"
const val KEY_REQUIRED_VERSION = "android_force_update_required_version"
const val KEY_UPDATE_URL = "android_force_update_store_url"
const val MINIMUM_FETCH_INTERVAL = 60L
}
}

data class UpdateRequiredModel(
val updateUrl: String? = null
)

and use ForceUpdateChecker in your class that you want to check the incoming updates. eg: Splash Screen

@Inject
lateinit var forceUpdateChecker: ForceUpdateChecker

private fun updateChecker() {
forceUpdateChecker.checkForceUpdateRequired { updateRequiredModel ->
if (updateRequiredModel != null) {
// pop up a non-cancellable dialog for giving information about new version
} else {
// do something
}
}
}

Conclusion

Firebase Remote Config simplifies the process of implementing forced app updates, ensuring that users have the latest version of your app containing critical fixes and features. By following the steps outlined in this article, you can enhance your app’s stability, security, and user experience while maintaining control over the update process.

That’s all. Thank you for reading!

References:

https://firebase.google.com/docs/remote-config/get-started?platform=android

--

--