Konfigure — better app configuration using Kotlin

Konfigure — better app configuration using Kotlin

November 11 2019

If you work on an application which uses Firebase Remote Config or something similar, you’ve probably wanted to test remote changes and run in to some trouble. Making sure config changes work before shipping them to the public can be painful without complex bespoke solutions. We wanted to make it easier for both our developers and our testers, so we developed Konfigure.

What is Konfigure?

Konfigure makes the use of tools like Firebase Remote Config easy by simplifying what it takes to wire up properties to actual remote values, saving you time and making things tidier. It’s built for extension, and can do a lot out of the box. Let’s explore some of the things that Konfigure is.

Konfigure is a Firebase Remote Config Wrapper

var isSomethingEnabled: Boolean by config()

That magic one-liner corresponds to a key (isSomethingEnabled) in Firebase Remote config. We can immediately start using it in code, and when we change the value of that key in Firebase, our code now uses it!

if (config.isSomethingEnabled) {    
    TODO("Enable something")
}

Konfigure is a debugging tool

Say you wanted to toggle the value of the isSomethingEnabled key without changing it in Firebase. We can override it by setting the value of that property.

// Debugging my feature toggle
config.isSomethingEnabled = true

That’s handy! But, what if you didn’t want to make a code change to toggle that value? Easy. Just install the konfigure-android module, implement ConfigProvider in your Application class and launch the ConfigActivity. You’ll be greeted with a UI, which you can make more descriptive by adding metadata to your property.


You’ve overridden something, nice! But, how do you persist that change across app restarts? Easy. Just use the provided SharedPreferencesOverrideHandler for persisting your changes to disk.

class AppConfig(context: Context): Config(    
    configSources = listOf(FirebaseRemoteConfigSource()),    
    overrideHandler = SharedPreferencesOverrideHandler(context)
) {    
    var isSomethingEnabled: Boolean by config()
}

Konfigure is a.. SharedPreferences wrapper?

Like what you’ve seen so far, but don’t have any remote configuration? Turns out you don’t need it to use Konfigure! Starting fresh, without existing SharedPreferences? All you need is to use the SharedPreferencesOverrideHandler

class AppConfig(context: Context): Config(    
    configSources = listOf(),    
    overrideHandler = SharedPreferencesOverrideHandler(context)
) {    
    var isSomethingEnabled: Boolean by config()
}

Have an existing SharedPreferences setup? Write your own config source and use it in place of, or alongside Firebase. All you need to do is expose a map of keys to Any value.

class ExistingSharedPreferencesSource(    
    sharedPrefs: SharedPreferences
): ConfigSource {    
    override val all: Map<String, Any> get() = sharedPrefs.all
}

Want to use existing SharedPreferences, but your keys aren’t the same as what you want your properties to look like? Pass in a different key to use!

var existingPref: Boolean by config(key = "existing_preference")

Konfigure is even more than that!

We’ve barely scratched the surface, but to not bore you with examples here’s a list of some of the useful things you can do:

Check it out!

Konfigure is available on GitHub — full installation and implementation instructions are there.