package com.jdroid.android.firebase.remoteconfig;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue;
import com.jdroid.android.application.AbstractApplication;
import com.jdroid.android.firebase.FirebaseAppModule;
import com.jdroid.java.collections.Maps;
import com.jdroid.java.concurrent.ExecutorUtils;
import com.jdroid.java.utils.LoggerUtils;
import org.slf4j.Logger;
import java.util.List;
import java.util.Map;
public class FirebaseRemoteConfigHelper {
private static final Logger LOGGER = LoggerUtils.getLogger(FirebaseRemoteConfigHelper.class);
private static FirebaseRemoteConfig firebaseRemoteConfig;
private static int retryCount = 0;
static void init() {
firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings.Builder configSettingsBuilder = new FirebaseRemoteConfigSettings.Builder();
configSettingsBuilder.setDeveloperModeEnabled(!AbstractApplication.get().getAppContext().isProductionEnvironment());
firebaseRemoteConfig.setConfigSettings(configSettingsBuilder.build());
List<RemoteConfigParameter> remoteConfigParameters = AbstractApplication.get().getRemoteConfigParameters();
if (remoteConfigParameters != null) {
Map<String, Object> defaults = Maps.newHashMap();
for (RemoteConfigParameter each : remoteConfigParameters) {
Object defaultValue = each.getDefaultValue();
if (defaultValue != null) {
defaults.put(each.getKey(), defaultValue);
}
}
firebaseRemoteConfig.setDefaults(defaults);
}
fetch(0, true);
}
public static void fetchNow() {
fetch(0, false);
}
public static void fetch(final long cacheExpirationSeconds, final Boolean setExperimentUserProperty) {
if (firebaseRemoteConfig != null) {
Task<Void> task = firebaseRemoteConfig.fetch(cacheExpirationSeconds);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
retryCount = 0;
LOGGER.debug("Firebase Remote Config fetch succeeded");
// Once the config is successfully fetched it must be activated before newly fetched values are returned.
Boolean result = firebaseRemoteConfig.activateFetched();
// true if there was a Fetched Config, and it was activated. false if no Fetched Config was found, or the Fetched Config was already activated.
LOGGER.debug("Firebase Remote Config activate fetched result: " + result);
if (setExperimentUserProperty) {
final List<RemoteConfigParameter> remoteConfigParameters = AbstractApplication.get().getRemoteConfigParameters();
if (remoteConfigParameters != null) {
ExecutorUtils.execute(new Runnable() {
@Override
public void run() {
for (RemoteConfigParameter each : remoteConfigParameters) {
if (each.isUserProperty()) {
String experimentVariant = FirebaseRemoteConfig.getInstance().getString(each.getKey());
FirebaseAppModule.get().getFirebaseAnalyticsHelper().setUserProperty(each.getKey(), experimentVariant);
}
}
}
});
}
}
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
LOGGER.error("Firebase Remote Config fetch failed", exception);
retryCount++;
if (retryCount <= 3) {
Bundle bundle = new Bundle();
bundle.putLong(FirebaseRemoteConfigFetchCommand.CACHE_EXPIRATION_SECONDS, cacheExpirationSeconds);
bundle.putBoolean(FirebaseRemoteConfigFetchCommand.SET_EXPERIMENT_USER_PROPERTY, setExperimentUserProperty);
new FirebaseRemoteConfigFetchCommand().start(bundle);
}
}
});
} else {
AbstractApplication.get().getExceptionHandler().logWarningException("Ignoring Firebase Remote Config fetch, because it wasn't initialized yet.");
}
}
@Nullable
public static FirebaseRemoteConfig getFirebaseRemoteConfig() {
return firebaseRemoteConfig;
}
private static FirebaseRemoteConfigValue getFirebaseRemoteConfigValue(RemoteConfigParameter remoteConfigParameter) {
if (firebaseRemoteConfig == null) {
return new StaticFirebaseRemoteConfigValue(remoteConfigParameter);
} else {
return firebaseRemoteConfig.getValue(remoteConfigParameter.getKey());
}
}
public static String getString(RemoteConfigParameter remoteConfigParameter) {
FirebaseRemoteConfigValue firebaseRemoteConfigValue = getFirebaseRemoteConfigValue(remoteConfigParameter);
Object value;
if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_STATIC) {
value = remoteConfigParameter.getDefaultValue();
} else {
value = firebaseRemoteConfigValue.asString();
}
log(remoteConfigParameter, firebaseRemoteConfigValue, value);
return (String)value;
}
public static Boolean getBoolean(RemoteConfigParameter remoteConfigParameter) {
FirebaseRemoteConfigValue firebaseRemoteConfigValue = getFirebaseRemoteConfigValue(remoteConfigParameter);
Object value;
if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_STATIC) {
value = remoteConfigParameter.getDefaultValue();
} else {
value = firebaseRemoteConfigValue.asBoolean();
}
log(remoteConfigParameter, firebaseRemoteConfigValue, value);
return (Boolean)value;
}
public static Double getDouble(RemoteConfigParameter remoteConfigParameter) {
FirebaseRemoteConfigValue firebaseRemoteConfigValue = getFirebaseRemoteConfigValue(remoteConfigParameter);
Object value;
if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_STATIC) {
value = remoteConfigParameter.getDefaultValue();
} else {
value = firebaseRemoteConfigValue.asDouble();
}
log(remoteConfigParameter, firebaseRemoteConfigValue, value);
return (Double)value;
}
public static Long getLong(RemoteConfigParameter remoteConfigParameter) {
FirebaseRemoteConfigValue firebaseRemoteConfigValue = getFirebaseRemoteConfigValue(remoteConfigParameter);
Object value;
if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_STATIC) {
value = remoteConfigParameter.getDefaultValue();
} else {
value = firebaseRemoteConfigValue.asLong();
}
log(remoteConfigParameter, firebaseRemoteConfigValue, value);
return (Long)value;
}
private static void log(RemoteConfigParameter remoteConfigParameter, FirebaseRemoteConfigValue firebaseRemoteConfigValue, Object value) {
if (LoggerUtils.isEnabled()) {
String source = null;
if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_STATIC) {
source = "Static";
} else if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_REMOTE) {
source = "Remote";
} else if (firebaseRemoteConfigValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT) {
source = "Default";
}
LOGGER.info("Loaded Firebase Remote Config. Source [" + source + "] Key [" + remoteConfigParameter.getKey() + "] Value [" + value + "]");
}
}
}