Remote Settings
Main purpose of RemoteSettingsProvider is to fetch a remote settings config. It's mandatory to
request remote settings on PAanalytics initialization.
Retrieve the
RemoteSettingsProviderinstance.val remoteSettingsProvider = PAanalytics.getInstance().remoteSettingsProvider()Request remote settings using
RemoteSettingsProviderinstance.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: Ajava.lang.reflect.Typeguiding 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:
Cache Check: If a recent value (within 10 minutes) exists in cache, it is emitted immediately.
Remote Fetch: Otherwise, a network request is performed (honoring the optional
timeoutMs).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.
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)
// }
}