Skip to main content

Remote Settings

Main purpose of RemoteSettingsProvider is to fetch a remote settings config. It's mandatory to request remote settings on PAanalytics initialization.

  1. Retrieve the RemoteSettingsProvider instance.

    val remoteSettingsProvider = PAanalytics.getInstance().remoteSettingsProvider()
  2. Request remote settings using RemoteSettingsProvider instance.

     val settingsRequestParams = SettingsRequestParams(
    isTest = false, // use true only in dev builds
    userId = userId
    )
    remoteSettingsProvider.requestSettings(settingsRequestParams)

Remote Settings Callbacks

You can setup a callback to listen for a settings request response

val settingsCallback = object: SettingsCallback {
override fun onReceive(settingsInfo: SettingsInfo) {
/* your code */
}
}
remoteSettingsProvider.addSettingsCallback(settingsCallback, true)

the SettingsInfo response can contain one of the following AppliedState value:

AppliedState.DEFAULT - if neither cache, nor remote is available AppliedState.REMOTE - if remote settings were fetched and applied bt PAnalytics AppliedState.CACHE - if only the cached settings are available at this moment

and isApplied boolean flag which indicates if settings response was applied or not

Running experiments

Each A/B experiment has own name and variants, i.e set of parameters that are considered to be applied to affect on business logic or\and UI appearance. Active experiments are fetched through Remote Settings with "experiments" key.

To use this feature make sure that you have configured your experiments that is shown above in this doc in the configurations section.

Please note It is not recommended to use only getExperimentVariant, consider to use runExperiment.

Running experiments

To run experiment just call the following method:

val variants = HashMap<String, Runnable>()
variants["v1"] = Runnable {
// actions for v1 variant
}
PAanalytics.getInstance().runExperiment("example_experiment_id", {
// actions for original variant
}, variants)

Get variant for an experiment

To get the variant for a specific experiment just call the following method:

PAanalytics.getInstance().getExperimentVariant("example_experiment_id")

Exclusive Settings with tag

Remote Settings Store

A RemoteSettingsStore provides a reactive, type-safe way to observe remote configuration values tagged to a specific context. Under the hood, it fetches values from the server (or cache) and emits updates via Kotlin Flow, automatically handling caching, experiments, segments, and failures.


1. Obtaining an Instance

Use the Analytics SDK entry point to obtain a RemoteSettingsStore for a given tag. You can optionally specify a request timeout (in milliseconds).

// Default timeout
val defaultStore: RemoteSettingsStore =
PAnalytics.getInstance()
.provideTagRemoteSettingsStore(tag = "user-profile")

// Custom timeout (e.g. 100ms)
val fastStore: RemoteSettingsStore =
PAnalytics.getInstance()
.provideTagRemoteSettingsStore(tag = "user-profile", timeoutMs = 100)

Why specify timeoutMs?

  • Controls the maximum time allowed for the remote fetch.
  • Shorter timeouts will fast failure, so you’ll fall back to cached values more quickly.
  • Longer or default timeouts for non-critical settings to improve reliability on slow networks.

2. Streaming a Setting

Call stream with:

  • key: A unique string identifier for your setting.
  • type: A java.lang.reflect.Type guiding JSON deserialization (e.g., MyConfig::class.java).
  • defaultValue: Fallback if remote fetch and cache both miss.
// Define your settings data class
data class FeatureToggle(val enabled: Boolean = false)

// Stream the setting
val featureFlow: Flow<FeatureToggle> =
defaultStore.stream(
key = "feature_toggle",
type = FeatureToggle::class.java,
defaultValue = FeatureToggle()
)

// Collect updates in a coroutine
lifecycleScope.launch {
featureFlow.collect { config ->
if (config.enabled) showNewUI() else hideNewUI()
}
}

3. How It Works

When you call stream, the store follows this high-level flow:

  1. Cache Check: If a recent value (within 10 minutes) exists in cache, it is emitted immediately.

  2. Remote Fetch: Otherwise, a network request is performed (honoring the optional timeoutMs).

  3. Emit & Store:

    • On success, the fresh value is emitted and saved to cache.
    • On failure (or cancellation), the store falls back to the cached value if available, or the provided defaultValue.
  4. Deserialization: The raw JSON is converted into your typed model via Gson.

All operations run on an IO dispatcher to keep your main thread free.


4. Integrating with Koin

Provide a singleton RemoteSettingsStore by default, calling PAnalytics.getInstance() inline. If desired, you can switch to a factory for per-injection instances.

import org.koin.dsl.module
import org.koin.androidx.viewmodel.dsl.viewModel

val myModule = module {
single<RemoteSettingsStore> { (tag: String, timeoutMs: Long?) ->
PAnalytics.getInstance()
.provideTagRemoteSettingsStore(tag = tag, timeoutMs = timeoutMs)
}

// If you prefer, use factory instead:
// factory<RemoteSettingsStore> { (tag: String, timeoutMs: Long?) ->
// PAnalytics.getInstance()
// .provideTagRemoteSettingsStore(tag = tag, timeoutMs = timeoutMs)
// }
}