HOW TO CHECK FOR UPDATE IN APP AND DISPLAY DIALOG IN ANDROID/Kotlin USING FIREBASE REMOTE CONFIG
Please Subscribe Youtube| Like Facebook | Follow Twitter
For Java follow this article
Introduction
In this article we will learn how to implement update check and then display alert dialog in your android app using firebase remote configuration. When you have updated your app in Play Store and want to display alert dialog to notify users that are using previous/older version of your app to go to Play Store for update.
Our Example
In our example code we will first setup firebase remote config and save our current app version code value to server-side configuration parameter (key/value) at firebase. On app start we will check current value of our app version code and then compare it to the remote value at firebase. If remote app version code value is greater than our current app version code value then we will display alert dialog to user for updating app. Therefore whenever we update our app at Play Store, we will save that current app version code value in firebase remote config.
Requirements:
- Android Project/App in which update check to be added
- Firebase Project
Note: First you need to create Firebase Project and then connect your app to it. You can follow this article to set it up.
Tip: You can change app version code at app level build.gradle file in defaultConfig block.
Steps
Follow below steps
1) Create remote key/value parameter version_code at firebase remote config.
2) Implement update check logic
3) Run and test your app.
1) Create remote key/value parameter version_code at firebase remote config.
First go to Firebase and open your Firebase Project and click on Remote Config.
Enter details in parameter object: Parameter Key = version_code, Default value = 0, Description = Check For Update. Then click on add parameter.
After adding parameter click on publish changes
2) Implement update check logic
First add firebase config library at app level build.gradle file
implementation 'com.google.firebase:firebase-config:19.1.4'
On app start we have called initRemoteConfig() method, which will initialize Firebase Remote Config Object. We have set current app version code value of our running app in default Hash Map and added it in setDefaultsAsync() method. Default values are used for safety if on backend version_code is not set in remote config.
Then we have set configuration of remote config using setConfigSettingsAsync() method in which minimum fetch interval value is specified. This defines minimum interval between successive fetches calls in seconds. Default value is 12 (12 hours) but during development set it to 0 to retrieve value from firebase server immediately. During production set it to 12 to save battery and data consumption.
After setting we have called fetch() method which will fetch value from remote config, on complete we have called activate() method which will activate most recently fetch config value from firebase server. After activation we will get latest app version code value from remote config and will call checkForUpdate() method to check if update is available.
private fun initRemoteConfig() {
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
//Setting the Default Map Value with the current app version code
//default values are used for safety if on backend version_code is not set in remote config
val firebaseDefaultMap = HashMap<String, Any>()
firebaseDefaultMap[VERSION_CODE_KEY] = currentVersionCode
mFirebaseRemoteConfig!!.setDefaultsAsync(firebaseDefaultMap)
//setMinimumFetchIntervalInSeconds to 0 during development to fast retrieve the values
//in production set it to 12 which means checks for firebase remote config values for every 12 hours
mFirebaseRemoteConfig!!.setConfigSettingsAsync(
FirebaseRemoteConfigSettings.Builder()
.setMinimumFetchIntervalInSeconds(TimeUnit.HOURS.toSeconds(0))
.build())
//Fetching remote firebase version_code value here
mFirebaseRemoteConfig!!.fetch().addOnCompleteListener { task ->
if (task.isSuccessful) {
//activate most recently fetch config value
mFirebaseRemoteConfig!!.activate().addOnCompleteListener { task ->
if (task.isSuccessful) {
//calling function to check if new version is available or not
val latestAppVersion = mFirebaseRemoteConfig!!.getDouble(VERSION_CODE_KEY).toInt()
runOnUiThread { checkForUpdate(latestAppVersion) }
}
}
}
}
}
checkForUpdate() method will compare and display alert dialog to user for updating app If remote app version code value is greater than our current running app version code value.
private fun checkForUpdate(latestAppVersion: Int) {
if (latestAppVersion > currentVersionCode) {
val builder = AlertDialog.Builder(this)
builder.setTitle("Update")
builder.setMessage("New Version Available. Please Update App")
builder.setPositiveButton("Ok") { dialog, which ->
goToPlayStore()
updateDailog!!.dismiss()
}
builder.setNegativeButton("Cancel") { dialog, which -> updateDailog!!.dismiss() }
// create and show the alert dialog
updateDailog = builder.create()
updateDailog!!.show()
}
}
getCurrentVersionCode() method gets version code of current running app on user device.
private val currentVersionCode: Int
get() {
var versionCode = 1
try {
val pInfo = applicationContext.packageManager.getPackageInfo(applicationContext.packageName, 0)
versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
pInfo.longVersionCode.toInt()
} else {
pInfo.versionCode
}
} catch (e: PackageManager.NameNotFoundException) {
//log exception
}
return versionCode
}
goToPlayStore() method navigates user to playstore
private fun goToPlayStore() {
try {
val appStoreIntent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))
appStoreIntent.setPackage("com.android.vending")
startActivity(appStoreIntent)
} catch (exception: ActivityNotFoundException) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageName")))
}
}
Whole Code
project level build.gradle
buildscript {
ext.kotlin_version = '1.4.0-rc'
repositories {
jcenter()
google()
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.google.gms:google-services:4.3.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
app level build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
android {
compileSdkVersion 28
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.programtown.example"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.google.firebase:firebase-config:19.1.4'
implementation "androidx.core:core-ktx:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
repositories {
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
mavenCentral()
}
Here you can change version code (versionCode) of your app on new updates.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.programtown.example
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
import java.util.*
import java.util.concurrent.TimeUnit
class MainActivity : AppCompatActivity() {
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
private var updateDailog: AlertDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initRemoteConfig()
}
private fun initRemoteConfig() {
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
//Setting the Default Map Value with the current app version code
//default values are used for safety if on backend version_code is not set in remote config
val firebaseDefaultMap = HashMap<String, Any>()
firebaseDefaultMap[VERSION_CODE_KEY] = currentVersionCode
mFirebaseRemoteConfig!!.setDefaultsAsync(firebaseDefaultMap)
//setMinimumFetchIntervalInSeconds to 0 during development to fast retrieve the values
//in production set it to 12 which means checks for firebase remote config values for every 12 hours
mFirebaseRemoteConfig!!.setConfigSettingsAsync(
FirebaseRemoteConfigSettings.Builder()
.setMinimumFetchIntervalInSeconds(TimeUnit.HOURS.toSeconds(0))
.build())
//Fetching remote firebase version_code value here
mFirebaseRemoteConfig!!.fetch().addOnCompleteListener { task ->
if (task.isSuccessful) {
//activate most recently fetch config value
mFirebaseRemoteConfig!!.activate().addOnCompleteListener { task ->
if (task.isSuccessful) {
//calling function to check if new version is available or not
val latestAppVersion = mFirebaseRemoteConfig!!.getDouble(VERSION_CODE_KEY).toInt()
runOnUiThread { checkForUpdate(latestAppVersion) }
}
}
}
}
}
private fun checkForUpdate(latestAppVersion: Int) {
if (latestAppVersion > currentVersionCode) {
val builder = AlertDialog.Builder(this)
builder.setTitle("Update")
builder.setMessage("New Version Available. Please Update App")
builder.setPositiveButton("Ok") { dialog, which ->
goToPlayStore()
updateDailog!!.dismiss()
}
builder.setNegativeButton("Cancel") { dialog, which -> updateDailog!!.dismiss() }
// create and show the alert dialog
updateDailog = builder.create()
updateDailog!!.show()
}
}
private val currentVersionCode: Int
get() {
var versionCode = 1
try {
val pInfo = applicationContext.packageManager.getPackageInfo(applicationContext.packageName, 0)
versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
pInfo.longVersionCode.toInt()
} else {
pInfo.versionCode
}
} catch (e: PackageManager.NameNotFoundException) {
//log exception
}
return versionCode
}
private fun goToPlayStore() {
try {
val appStoreIntent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))
appStoreIntent.setPackage("com.android.vending")
startActivity(appStoreIntent)
} catch (exception: ActivityNotFoundException) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageName")))
}
}
companion object {
private const val VERSION_CODE_KEY = "version_code"
}
}
3) Run and test your app
Initially Our App version code is 1. We have updated our app and its version code is now became 2.
defaultConfig {
applicationId "com.programtown.example"
minSdkVersion 17
targetSdkVersion 28
versionCode 2
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
We have updated our app on play store, now we will change version code at firebase remote config to display update dialog to users who are using older version (version code 1) of app.
Go to remote config change version_code value to 2 and click on update then publish changes.
After updating value at firebase config, old version app user will get update dialog notification.
Conclusion
So in this post we have learned how to implement update check and display alert dialog in android application.
Please Subscribe Youtube| Like Facebook | Follow Twitter