How to integrate Remote Config in Android

How to integrate Remote Config in Android

Initial Steps

  1. If you haven't done so already, create a new project in the Firebase console.

  2. Click on "Add Firebase to your Android app" and follow the setup steps.

  3. When prompted, enter your app's package name, for example, com.android.myapp

  4. At the end, you'll download a google-services.json file. You can download this file again at any time.

  5. If you haven't done so already, copy this into your project's module folder, typically app/.

  6. In the Firebase console, enable Remote Config for your project.

  7. Once enabled, you can create new parameters for example isEnabled as boolean.

Add Firebase Remote Config to your app

Add the dependency for Firebase Remote Config to your app/build.gradle file:

dependencies {
    // ...
    // For Java (Works for Kotlin as well)
    implementation 'com.google.firebase:firebase-config:21.4.0'
    // Specifically For Kotlin
    implementation 'com.google.firebase:firebase-config-ktx:21.4.0'
}

Then sync your project.

Fetch parameter values from the Remote Config service

In Java

package com.android.myapp;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.FirebaseApp;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigException;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.google.firebase.remoteconfig.ktx.ConfigUpdate;
import com.google.firebase.remoteconfig.ktx.ConfigUpdateListener;
import com.google.tasks.OnCompleteListener;
import com.google.tasks.Task;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final String IS_ENABLED_KEY = "isEnabled";

    private FirebaseRemoteConfig remoteConfig;

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

        // Initialize Firebase Remote Config
        remoteConfig = FirebaseRemoteConfig.getInstance();

        // Fetch and activate the parameter values from the Remote Config service
        fetchIsEnabled();
    }

    // This is not real-time
    private void fetchIsEnabled() {
        FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
                .setMinimumFetchIntervalInSeconds(1)
                .build();

        remoteConfig.setConfigSettingsAsync(configSettings);
        remoteConfig.fetchAndActivate()
                .addOnCompleteListener(this, new OnCompleteListener<Boolean>() {
                    @Override
                    public void onComplete(@NonNull Task<Boolean> task) {
                        if (task.isSuccessful()) {
                            boolean updated = task.getResult();
                            Log.d(TAG, "Config params updated: " + updated);
                            // Check the parameter value and launch the appropriate activity
                            checkIsEnabledAndLaunchActivity();
                        } else {
                            // Handle errors
                            Log.e(TAG, "Fetch failed");
                        }
                    }
                });
    }

    // If you want to listen to the real-time changes
    private void setOnConfigUpdateListener() {
        remoteConfig.addOnConfigUpdateListener(new ConfigUpdateListener() {
            @Override
            public void onUpdate(@NonNull ConfigUpdate configUpdate) {
                Log.d(TAG, "Updated keys: " + configUpdate.getUpdatedKeys());
                if (configUpdate.getUpdatedKeys().contains("isEnabled")) {
                    remoteConfig.activate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
                        @Override
                        public void onComplete(@NonNull Task<Boolean> task) {
                            checkIsEnabledAndLaunchActivity();
                        }
                    });
                }
            }

            @Override
            public void onError(@NonNull FirebaseRemoteConfigException error) {
                Log.d(TAG, "Config update failed: " + error.getCode() + " " + error.getMessage());
            }
        });
    }

    private void checkIsEnabledAndLaunchActivity() {
        boolean isEnabled = remoteConfig.getBoolean(IS_ENABLED_KEY);
        if (isEnabled) {
            // Launch the enabled activity
            startActivity(new Intent(this, EnabledActivity.class));
            finish();
        } else {
            // Launch the disabled activity
            startActivity(new Intent(this, DisabledActivity.class));
            finish();
        }
    }
}

In Kotlin

package com.android.myapp

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.ktx.Firebase
import com.google.firebase.ktx.get
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfigSettings

class MainActivity : AppCompatActivity() {
    private val remoteConfig = Firebase.remoteConfig

    companion object {
        private const val TAG = "MainActivity"
        private const val IS_ENABLED_KEY = "isEnabled"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Fetch and activate the parameter values from the Remote Config service
        fetchIsEnabled()
    }

    //This is not realtime
    private fun fetchIsEnabled() {
        val configSettings = remoteConfigSettings {
            minimumFetchIntervalInSeconds = 1
        }
        remoteConfig.setConfigSettingsAsync(configSettings)
        remoteConfig.fetchAndActivate()
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val updated = task.result
                    Log.d(TAG, "Config params updated: $updated")
                    // Check the parameter value and launch the appropriate activity
                    checkIsEnabledAndLaunchActivity()
                } else {
                    // Handle errors
                }
            }
    }

        // If you want to listen to the real-time changes
        private fun setOnConfigUpdateListener() {
        remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {
            override fun onUpdate(configUpdate: ConfigUpdate) {
                Log.d(TAG, "Updated keys: " + configUpdate.updatedKeys)
                if (configUpdate.updatedKeys.contains("isEnabled")) {
                    remoteConfig.activate().addOnCompleteListener {
                        checkIsEnabledAndLaunchActivity()
                    }
                }
            }
            override fun onError(error: FirebaseRemoteConfigException) {
                Log.d(TAG, "Config update failed: ${error.code} ${error.message}")
            }
        })
    }

    private fun checkIsEnabledAndLaunchActivity() {
        val isEnabled = remoteConfig[IS_ENABLED_KEY].asBoolean()
        // Alternatively
        // val isEnabled = remoteConfig.getBoolean(IS_ENABLED_KEY)
        if (isEnabled) {
            // Launch the enabled activity
            startActivity(Intent(this, EnabledActivity::class.java))
            finish()
        } else {
            // Launch the disabled activity
            startActivity(Intent(this, DisabledActivity::class.java))
            finish()
        }
    }
}

You only need to call one function so call either setOnConfigUpdateListener() or fetchIsEnabled() according to your requirements.

If you only use checkIsEnabledAndLaunchActivity() without first using fetchIsEnabled() or setOnConfigUpdateListener(), your app will only check the value of IS_ENABLED_KEY from the local cache of Firebase Remote Config parameters.

This means that if you’ve made changes to IS_ENABLED_KEY on the Firebase console, those changes won’t be reflected in your app until the next fetch operation.

So, if you want your app to have the most up-to-date Remote Config parameters, fetch and activate the parameters before checking their values. Or simply use setOnConfigUpdateListener() If you don’t need the most up-to-date parameters and can work with potentially stale data, then you could use checkIsEnabledAndLaunchActivity() without fetchIsEnabled() or setOnConfigUpdateListener() This is generally not recommended.

Get parameter values

You can call getString(), getLong(), getDouble(), or getBoolean() to get parameter values