Search code examples
javaandroidfirebasefirebase-remote-config

How to handle a Remote Config instance inside a singleton


What I'm trying to do is to make a singleton of a Remote Config fetch in order to load it at first time in my SplashScreen.

While my splashscreen is loading I fetch the data with my remote config singleton once, and then, I just access the value inside each class that I need the value of that Remote Config

I'm doing this to prevent the users to see the changes while they are on the Activity, this is due a christmas theme that I'm making in order to show a custom layout with Remote config

All is working fine (sometimes) and the theme is changing all over the app with this singleton, but there are sometimes that the asynchronous fetch time that must take returns after my SplashScreen is loaded, so I can see the theme changed in the rest of my Activities but not in the main one after the SplashScreen

This is my singleton

public class PruebaSingleton {

    private boolean christmasEvent;
    private FirebaseRemoteConfig mFirebaseRemoteConfig;
    private static volatile PruebaSingleton _instance;

 private PruebaSingleton(){
        fetchRemoteConfig();
    }

    public synchronized static PruebaSingleton getInstance(){
        if(_instance == null){

            synchronized (PruebaSingleton.class) {
                if (_instance == null) _instance = new PruebaSingleton();
            }
        }

        return  _instance;
    }

    private void fetchRemoteConfig() {
        mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
        mFirebaseRemoteConfig.setConfigSettings(
                new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(BuildConfig.DEBUG)
                        .build());

        mFirebaseRemoteConfig.fetch(0).addOnCompleteListener(task -> {
            if (task.isSuccessful()) {

                 mFirebaseRemoteConfig.activateFetched();

            }

            christmasEvent = mFirebaseRemoteConfig.getBoolean("christmas_ottaa_mode");

        }).addOnFailureListener(e -> {

        });
    }
    public boolean isChristmasModeEnabled(){
        return christmasEvent;
    }

Now, after this, I just instantiate once this singleton to fetch the data of the remote config and impact my whole app.

At my SplashScreen onCreate()

PruebaSingleton.getInstance();

And then I just get the boolean value in all my Activities this way

PruebaSingleton.getInstance().isChristmasModeEnabled();

And then with that, I can change the theme.

The thing is that sometimes (not usually but it happened like 2 times in about 10 launches) the fetch from the singleton inside my SplashScreen gets the data after the splash screen sends to the first Activity, this causes my first Activity to not showup the theme but my others Activities does.

My question is

Is there anyway to handle the fetch while I'm in my SplashScreen ?

Thinking on making an interface will slowdown my SplashScreen a little bit untill all the fetch work is done at the singleton class, but also I dont want to show any popup dialog at the first Activity to tell users that is waiting for a fetch.

This is more of a performance issue because while the fetch is done, the splashscreen needs to go fast to the first activity and not wait more time to get the data, because if that happens I will reduce performance on the app trying to load a christmas theme.

Also the first fetch should work properly, the second launch will load the data that was fetched at first time and then wait for 12hs to request the new data, so I need to have all the Activities with the fetch value in true at the first time.


Solution

  • Your singleton needs to expose a way to let some other code attach a listener to know when the fetch is complete, similar to the way you're attaching a listener to the Task that performs a fetch. Or you can just expose the Task itself.

    The Task I'm referring to is returned by this:

    mFirebaseRemoteConfig.fetch(0)