Skip to main content
Supported on: Android SDK 1.0.33+
Remote config lets you ship app behavior changes without releasing a new app version. Define key-value pairs in the Console, target them by audience or experiment, and read them from the SDK at runtime.

How It Works

  1. You define remote config keys in the Console.
  2. The SDK fetches the bundle (Firestore + REST fallback) when the app starts and listens for live updates.
  3. Your app reads values via AppDNA.remoteConfig.get(key) and the SDK serves the latest cached value.
  4. When values change server-side, an onChanged callback fires so your UI can react.
Remote config values are cached locally and survive offline use. The cache uses a configurable TTL (default 1 hour) — see Offline Support for cache behavior.

Get a Value

The Android SDK exposes a single typed-as-Any? getter — cast to the concrete type you stored:
val welcomeMessage = AppDNA.remoteConfig.get("welcome_message") as? String
val tutorialEnabled = AppDNA.remoteConfig.get("tutorial_enabled") as? Boolean
val maxItems = (AppDNA.remoteConfig.get("max_items") as? Number)?.toInt()
val pricing = AppDNA.remoteConfig.get("pricing_tiers") as? Map<String, Any>
Return type is Any?. The SDK preserves the value shape the Console stored (string, number, boolean, list, map). Use as? casts to coerce to the expected type and default with ?: when the key is missing. The top-level convenience method AppDNA.getRemoteConfig(key) is equivalent to AppDNA.remoteConfig.get(key).

Get All Values

Retrieve the entire config map:
val all = AppDNA.remoteConfig.getAll()
for ((key, value) in all) {
    Log.d("Config", "$key = $value")
}
Returns Map<String, Any> (empty map if config has not loaded yet).

Force Refresh

Force the SDK to fetch the latest configuration from the server, bypassing the TTL cache:
AppDNA.remoteConfig.refresh()
This is useful during development to test new config values without waiting for the TTL. The convenience method AppDNA.forceRefreshConfig() is equivalent.
Refreshing too frequently in production may impact performance and consume bandwidth. Rely on the default TTL for normal operation.

Listen for Changes

Register a callback that fires whenever remote config values change (live Firestore update or TTL refresh):
AppDNA.remoteConfig.onChanged { configs ->
    Log.d("Config", "${configs.size} values updated")
    // configs is the full Map<String, Any> snapshot
    val newMessage = configs["welcome_message"] as? String
    refreshUiWith(newMessage)
}
The callback receives the full config snapshot — not just changed keys. Re-read whatever you care about and update your UI accordingly.

When Config Refreshes

The SDK refreshes remote config automatically:
  • On app launch — if the cached config has expired (default TTL: 1 hour)
  • On return from background — same TTL check
  • Live Firestore updates — when the Console publishes new values, the SDK applies them immediately via the active real-time listener
You rarely need to trigger a refresh manually. If a fetch fails (no connectivity, timeout), the SDK continues using the cached values until the next successful fetch.
The config TTL is configurable via AppDNAOptions(configTTL = 1800L) (in seconds). The default is 3600 seconds (1 hour).

Module Access

val remoteConfig = AppDNA.remoteConfig

Module Methods

MethodSignatureDescription
getget(key: String): Any?Get a remote config value by key
getAllgetAll(): Map<String, Any>Get a snapshot of all remote config values
refreshrefresh()Force a fresh fetch from the server (bypasses TTL)
onChangedonChanged(callback: (Map<String, Any>) -> Unit)Register a callback for live config updates

Targeting and Variants

Remote config values can be targeted by audience attributes (country, app version, user trait) or scoped to experiment variants. The SDK automatically resolves the correct value for the current user based on the active config bundle. No code changes are required — variant resolution is fully server-side.

Full Example

import ai.appdna.sdk.AppDNA
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class HomeActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        configureUi()

        // React to live config updates
        AppDNA.remoteConfig.onChanged {
            runOnUiThread { configureUi() }
        }
    }

    private fun configureUi() {
        val title = AppDNA.remoteConfig.get("home_title") as? String ?: "Welcome"
        val showBanner = AppDNA.remoteConfig.get("show_promo_banner") as? Boolean ?: false
        val bannerText = AppDNA.remoteConfig.get("promo_banner_text") as? String ?: ""

        titleView.text = title
        if (showBanner) {
            promoBanner.text = bannerText
            promoBanner.visibility = View.VISIBLE
        } else {
            promoBanner.visibility = View.GONE
        }
    }
}

Configuration in Console

Manage remote config in the AppDNA Console:
  1. Navigate to Settings → Remote Config.
  2. Add a new key with a default value.
  3. Optionally add variants targeted by audience or experiment.
  4. Publish the config to push it to the SDK.
Remote config values are cached locally. To test new values immediately, call AppDNA.remoteConfig.refresh() or wait for the TTL to expire.

Next Steps