Firebase Remote Config - check if value exists
Asked Answered
N

4

5

I want to implement kind of a proxy for some boolean values in my app. The logic would be as follows:

  1. I receive a set of values from my back-end
  2. I have some of these values set in Firebase as well
  3. When using a value in the app, I first check if it exists in Firebase

    3.1. If it exists, take the Firebase value

    3.2. If it does not exist, take the backend value

The question is - how can I check if the value exists in Firebase Remote Config?

Nambypamby answered 15/12, 2017 at 13:36 Comment(7)
Can I ask what is the use case for doing so? What feature are you trying to power through this?Vacillatory
Or are you building this as a backup if someone messes up in Remote Config default values?Vacillatory
The other way around - if someone messes something in the back-end, I want to be able to quickly override the value the users get in their app (as I can not edit the back-end and it usually takes lota of time to get something to change in it)Nambypamby
What happens if you do a getString() on a key which is neither defined in the defaults.xml or in the remote config console?Vacillatory
You will get "", which is the solution I posted below :DNambypamby
Yes, I saw that. I was more interested in the use case :)Vacillatory
Thanks for sharing! It'd be so cool if Remote Config could replace all your literals while you are writing code. So if you write String var_foo="bar", it could show a code hint, saying convert var_foo to remote config key.Vacillatory
N
10

I have found the solution:

Firebase Remote Config fetches ALL values as Strings and only then maps them to other types in convenience methods such as getBoolean(), getLong() etc.

Therefore, a boolean config value existence can be checked as follows:

String value = firebaseRemoteConfig.getString("someKey");

if(value.equals("true")){
    //The value exists and the value is true
} else if(value.equals("false")) {
    //The value exists and the value is false
} else if(value.equals("")) {
    //The value is not set in Firebase
}

Same goes for other types, i.e. a long value set to 64 on firebase will be returned from getString() as "64".

Nambypamby answered 18/12, 2017 at 13:11 Comment(1)
Note that this is only valid if no default values are defined via setDefaultsAsync(). When you did define a default, getString() will return the default value.Popliteal
T
13

I found another way, maybe useful for someone else landing here:

val rawValue = remoteConfig.getValue(key)
val exists = rawValue.source == FirebaseRemoteConfig.VALUE_SOURCE_REMOTE

In this case exists will be true only if the value is returned from remote (and and has not been set as default or static provided value). The accepted answer is error prone as does not consider the case where the empty String is a valid String returned from remote

Here the docs for FirebaseRemoteConfigValue

Tejada answered 5/4, 2020 at 16:17 Comment(1)
This is the correct answer. For C#: bool exists = rawValue.source == ValueSource.RemoteValue; Documentation here: firebase.google.com/docs/reference/unity/namespace/firebase/…Alliber
N
10

I have found the solution:

Firebase Remote Config fetches ALL values as Strings and only then maps them to other types in convenience methods such as getBoolean(), getLong() etc.

Therefore, a boolean config value existence can be checked as follows:

String value = firebaseRemoteConfig.getString("someKey");

if(value.equals("true")){
    //The value exists and the value is true
} else if(value.equals("false")) {
    //The value exists and the value is false
} else if(value.equals("")) {
    //The value is not set in Firebase
}

Same goes for other types, i.e. a long value set to 64 on firebase will be returned from getString() as "64".

Nambypamby answered 18/12, 2017 at 13:11 Comment(1)
Note that this is only valid if no default values are defined via setDefaultsAsync(). When you did define a default, getString() will return the default value.Popliteal
G
1

Firebase Remote Config (FRC), actually provides 3 constants to know from where is the value retrieved with getValue(forKey) (documentation)

  • VALUE_SOURCE_DEFAULT --> value from default set by user
  • VALUE_SOURCE_REMOTE --> value from remote server
  • VALUE_SOURCE_STATIC --> value returned is default (FRC don't have the key)

Knowing this, you can do a "wrapper" like this:

class FirebaseRemoteConfigManager {
.....

    override fun getBoolean(forKey: String): Boolean? = getRawValue(forKey)?.asBoolean()

    override fun getString(forKey: String): String? = getRawValue(forKey)?.asString()

    override fun getDouble(forKey: String): Double? = getRawValue(forKey)?.asDouble()

    override fun getLong(forKey: String): Long? = getRawValue(forKey)?.asLong()

    private fun getRawValue(forKey: String): FirebaseRemoteConfigValue? {
        val rawValue = remoteConfig.getValue(forKey)
        return if (rawValue.source == FirebaseRemoteConfig.VALUE_SOURCE_STATIC) null else rawValue
    }
...
}

If you get a null, you know the key don't exist in FRC. Take care of using default values as "not exist", because maybe in your FRC you want to set this value, and you will have a false positive

Godbey answered 8/9, 2021 at 10:58 Comment(0)
F
0

Remote Config already does this, as described in the documentation. You're obliged to provide default values for parameters that haven't been defined in the console. They work exactly as you describe, without having to do any extra work. These defaults will be used until you perform a fetch. If the value is defined in the console, then it will be used instead of the default.

Florenceflorencia answered 15/12, 2017 at 16:18 Comment(4)
The problem is, the values would be dynamic. I want to be able to add a firebase proxy value without redeploying the app. Also, there is no obligation to define defaults from what I have seen. It just returns the default value for that data type (false, "" or 0)Nambypamby
I guess I don't understand what you're trying to do. What's a "firebase proxy value"?Florenceflorencia
These firebase values are supposed to be master values. So if there is one in firebase, use that. If not, use the one retrieved from the backend. And I want to be able to iterate all back-end values, check if there is an override in firebase and use that if so.Nambypamby
I don't think you're going to be able to know if a parameter has a value in the console unless you place a special value there that indicates to the app not to use it.Florenceflorencia

© 2022 - 2024 — McMap. All rights reserved.