How to check for update in app and display dialog in Android/Java using Firebase Remote Config

Share Post
  •  
  •  
  •  
  • 2
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    2
    Shares

Please Subscribe Youtube| Like Facebook | Follow Twitter

For Kotlin 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:

  1. Android Project/App in which update check to be added
  2. 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 void 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
	HashMap<String, Object> firebaseDefaultMap = new HashMap<>();
	firebaseDefaultMap.put(VERSION_CODE_KEY, getCurrentVersionCode());
	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(
			new FirebaseRemoteConfigSettings.Builder()
					.setMinimumFetchIntervalInSeconds(TimeUnit.HOURS.toSeconds(0))
					.build());

	//Fetching remote firebase version_code value here
	mFirebaseRemoteConfig.fetch().addOnCompleteListener(new OnCompleteListener<Void>() {
		@Override
		public void onComplete(@NonNull Task<Void> task) {
			if (task.isSuccessful()) {
				//activate most recently fetch config value
				mFirebaseRemoteConfig.activate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
					@Override
					public void onComplete(@NonNull Task<Boolean> task) {
						if(task.isSuccessful()){
							//calling function to check if new version is available or not
							final int latestAppVersion = (int) mFirebaseRemoteConfig.getDouble(VERSION_CODE_KEY);
							runOnUiThread(new Runnable() {
								@Override
								public void run() {
									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 void checkForUpdate(int latestAppVersion) {
	if (latestAppVersion > getCurrentVersionCode()) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("Update");
		builder.setMessage("New Version Available.\n"+"Please Update App");
		builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				goToPlayStore();
				updateDailog.dismiss();
			}
		});
		builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int 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 int getCurrentVersionCode() {
	int versionCode=1;
	try {
		final PackageInfo pInfo = getApplicationContext().getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), 0);
		if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
			versionCode = (int) pInfo.getLongVersionCode();
		} else {
			versionCode = pInfo.versionCode;
		}
	} catch (PackageManager.NameNotFoundException e) {
		//log exception
	}
	return versionCode;
}

goToPlayStore() method navigates user to playstore

private void goToPlayStore() {
	try {
		Intent appStoreIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()));
		appStoreIntent.setPackage("com.android.vending");
		startActivity(appStoreIntent);
	} catch (android.content.ActivityNotFoundException exception) {
		startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
	}
}

Whole Code

app level build.gradle

Here you can change version code (versionCode) of your app on new updates.

apply plugin: 'com.android.application'
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'

}

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.java

package com.programtown.example;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    private FirebaseRemoteConfig mFirebaseRemoteConfig ;
    private static final String VERSION_CODE_KEY = "version_code";
    private AlertDialog updateDailog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initRemoteConfig();
    }

    private void 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
        HashMap<String, Object> firebaseDefaultMap = new HashMap<>();
        firebaseDefaultMap.put(VERSION_CODE_KEY, getCurrentVersionCode());
        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(
                new FirebaseRemoteConfigSettings.Builder()
                        .setMinimumFetchIntervalInSeconds(TimeUnit.HOURS.toSeconds(0))
                        .build());

        //Fetching remote firebase version_code value here
        mFirebaseRemoteConfig.fetch().addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    //activate most recently fetch config value
                    mFirebaseRemoteConfig.activate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
                        @Override
                        public void onComplete(@NonNull Task<Boolean> task) {
                            if(task.isSuccessful()){
                                //calling function to check if new version is available or not
                                final int latestAppVersion = (int) mFirebaseRemoteConfig.getDouble(VERSION_CODE_KEY);
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        checkForUpdate(latestAppVersion);
                                    }
                                });
                            }
                        }
                    });
                }
            }
        });
    }

    private void checkForUpdate(int latestAppVersion) {
        if (latestAppVersion > getCurrentVersionCode()) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Update");
            builder.setMessage("New Version Available.\n"+"Please Update App");
            builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    goToPlayStore();
                    updateDailog.dismiss();
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    updateDailog.dismiss();
                }
            });
            // create and show the alert dialog
            updateDailog = builder.create();
            updateDailog.show();
        }
    }

    private int getCurrentVersionCode() {
        int versionCode=1;
        try {
            final PackageInfo pInfo = getApplicationContext().getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), 0);
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                versionCode = (int) pInfo.getLongVersionCode();
            } else {
                versionCode = pInfo.versionCode;
            }
        } catch (PackageManager.NameNotFoundException e) {
            //log exception
        }
        return versionCode;
    }

    private void goToPlayStore() {
        try {
            Intent appStoreIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()));
            appStoreIntent.setPackage("com.android.vending");
            startActivity(appStoreIntent);
        } catch (android.content.ActivityNotFoundException exception) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
        }
    }
}

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.1"
        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


Share Post
  •  
  •  
  •  
  • 2
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    2
    Shares

Leave a Reply

Your email address will not be published. Required fields are marked *