API Reference

Value Accessors

Every SDK matches the Firebase SDK of its own platform: Firebase Android naming on Android and KMP, a native Swift API on iOS, and the familiar platform shapes on Flutter, React Native, Unity, and Web. Values resolve remote → in-app default → static zero-value, and accessors never block the calling thread.

MethodReturnsStatic Fallback
getString(key)String""
getBoolean(key)Booleanfalse
getLong(key)Long0
getDouble(key)Double0.0
getValue(key)RemoteConfigValueStatic value
getAll()Map<String, RemoteConfigValue>All known keys
getKeysByPrefix(prefix)Set<String>Empty set

getValue(key) returns a RemoteConfigValue with asString(), asBoolean(), asLong(), asDouble(), asByteArray(), and getSource() (REMOTE, DEFAULT, or STATIC).

Lifecycle Methods

MethodDescription
setDefaults(map)Register in-app defaults, persisted across cold starts. An XML variant setDefaults(context, R.xml.defaults) is also available. Call in onCreate.
setConfigSettings(settings)Tune minimumFetchIntervalSeconds (default 12h) and fetchTimeoutSeconds (default 60s).
fetch()Download the latest config without applying it. A suspend function.
activate()Promote the last fetched config. Returns a Boolean telling you whether values changed.
fetchAndActivate()Fetch + activate in one call. Returns a Boolean.
getInfo()Last fetch status (SUCCESS, FAILURE, THROTTLED, NO_FETCH_YET), last fetch time, active settings.
setCustomSignals(signals)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals. A suspend function.
addOnConfigUpdateListener { }Register a listener for config updates. Updates are delivered via data push notifications, and the listener fires when new values are activated. Remove with the returned registration.
reset()Clear all fetched and activated config, resetting to in-app defaults.
MethodReturnsStatic Fallback
config["key"] / configValue(forKey:)RemoteConfigValueStatic value
value.stringValueString""
value.boolValueBoolfalse
value.numberValueNSNumber0
value.dataValueDataEmpty data
value.jsonValueAny?nil
getString(key)String (convenience)""
keysWithPrefix(_:) / allKeys(from:)[String]Empty array

value.source reports remote, default, or static. The @RemoteConfigProperty(key:) wrapper connects a key directly to a SwiftUI property, and JSON parameters decode to Codable types through the subscript.

Lifecycle Methods

MethodDescription
AppSpike.shared.initialize(apiKey:modules:)Initialize the SDK with AppSpikeRemoteConfig.shared in modules. Get the instance afterwards with AppSpike.remoteConfig().
setDefaults(_:) / setDefaults(fromPlist:)Register in-app defaults from a dictionary or a plist.
configSettingsAssign RemoteConfigSettings(minimumFetchInterval:fetchTimeout:), defaults 12h and 60s.
fetch() / activate() / fetchAndActivate()async throws. fetchAndActivate() returns a fetch status enum such as .successFetchedFromRemote.
lastFetchTime / lastFetchStatusFetch metadata, same shape as Firebase.
setCustomSignals(_:)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals. Takes a dictionary or a CustomSignals.Builder.
addOnConfigUpdateListener / configUpdatesRegister a listener for config updates. Updates are delivered via data push notifications, and the listener fires when new values are activated. Available as a callback or an AsyncSequence.
reset()Clear all fetched and activated config, resetting to in-app defaults.
MethodReturnsStatic Fallback
getString(key)String""
getBoolean(key)Booleanfalse
getLong(key)Long0
getDouble(key)Double0.0
getValue(key)RemoteConfigValueStatic value
getAll()Map<String, RemoteConfigValue>All known keys
getKeysByPrefix(prefix)Set<String>Empty set

getValue(key) returns a RemoteConfigValue with asString(), asBoolean(), asLong(), asDouble(), asByteArray(), and getSource() (REMOTE, DEFAULT, or STATIC).

Lifecycle Methods

MethodDescription
setDefaults(map)Register in-app defaults from commonMain, persisted across cold starts.
setConfigSettings(settings)Tune minimumFetchIntervalSeconds (default 12h) and fetchTimeoutSeconds (default 60s).
fetch()Download the latest config without applying it. A suspend function.
activate()Promote the last fetched config. Returns a Boolean telling you whether values changed.
fetchAndActivate()Fetch + activate in one call. Returns a Boolean.
getInfo()Last fetch status (SUCCESS, FAILURE, THROTTLED, NO_FETCH_YET), last fetch time, active settings.
setCustomSignals(signals)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals. A suspend function.
addOnConfigUpdateListener { }Register a listener for config updates. Updates are delivered via data push notifications, and the listener fires when new values are activated. Remove with the returned registration.
reset()Clear all fetched and activated config, resetting to in-app defaults.
MethodReturnsStatic Fallback
getString(key)String''
getBool(key)boolfalse
getInt(key)int0
getDouble(key)double0.0
getValue(key)RemoteConfigValueStatic value
getAll()Map<String, RemoteConfigValue>All known keys
getKeysByPrefix(prefix)Set<String>Empty set

getValue(key) returns a RemoteConfigValue with asString(), asBool(), asInt(), asDouble(), asBytes(), and source.

Lifecycle Methods

MethodDescription
AppSpike.instance.initialize(apiKey:modules:)Initialize the SDK with the Remote Config instance in modules.
ensureInitialized()Completes once persisted state is loaded.
setDefaults(Map)Persisted in-app defaults.
setConfigSettings(RemoteConfigSettings)fetchTimeout and minimumFetchInterval as Durations.
setCustomSignals(Map)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals.
fetch({minimumFetchInterval})Fetch + evaluate without applying. The optional argument overrides the interval for one call.
activate() / fetchAndActivate()Both return a bool telling you whether values changed.
lastFetchTime / lastFetchStatus / settingsFetch metadata.
onConfigUpdatedRegister a listener for config updates. Updates are delivered via data push notifications, and the listener fires when new values are activated. A Stream<RemoteConfigUpdate> of changed-key sets.
reset()Clear all config state.
MethodReturnsStatic Fallback
getString(key)string''
getBoolean(key)booleanfalse
getNumber(key)number0
getValue(key)ConfigValueStatic value
getAll()Record<string, ConfigValue>All known keys
getKeysByPrefix(prefix)string[]Empty array

getValue(key) returns a ConfigValue with asString(), asBoolean(), asNumber(), and getSource() ('remote', 'default', or 'static').

Lifecycle Methods

MethodDescription
AppSpike.initialize({...})Initialize with apiKey, appVersion/appBuild for version targeting, and modules: [appSpikeRemoteConfig].
ensureInitialized()Resolves once persisted state is loaded.
setDefaults(obj)In-app defaults. setDefaultsFromResource is not supported, pass the object directly.
setConfigSettings({...})minimumFetchIntervalMillis and fetchTimeMillis, same shape as Firebase.
setCustomSignals(obj)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals.
fetch(seconds?) / activate() / fetchAndActivate()Same promises as Firebase. fetchAndActivate() resolves to whether values changed.
onConfigUpdated(cb)Register a listener for config updates. Updates are delivered via data push notifications, and the listener fires when new values are activated. Returns an unsubscribe function. No error argument.
lastFetchTime / lastFetchStatus / settingsFetch metadata. lastFetchTime is -1 when never fetched.
reset()Clear all config state.
MethodReturnsStatic Fallback
GetValue(key)ConfigValueStatic value
value.StringValuestring""
value.BooleanValueboolfalse
value.LongValuelong0
value.DoubleValuedouble0.0
GetString / GetBoolean / GetLong / GetDoubleTyped gettersZero values

ConfigValue accessors never throw. A value that cannot be converted reads as the zero value instead of raising FormatException, and typed getters fall back to your in-app default.

Lifecycle Methods

MethodDescription
AppSpikeSdk.InitializeAsync(apiKey, modules)One API key, no config files. Pass AppSpikeRemoteConfig.DefaultInstance in modules.
SetDefaultsAsync(dict)Persisted in-app defaults.
SetConfigSettingsAsync(ConfigSettings)MinimumFetchIntervalInMilliseconds and FetchTimeoutInMilliseconds.
SetCustomSignalsAsync(builder)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals.
FetchAsync(TimeSpan?) / ActivateAsync() / FetchAndActivateAsync()Same lifecycle as Firebase for Unity. The optional TimeSpan overrides the fetch interval for one call.
InfoFetchTime, LastFetchStatus, LastFetchFailureReason.
OnConfigUpdateListenerRegister a listener for config updates. Updates are delivered via data push notifications, and the listener fires when new values are activated. A standard C# event.
MethodReturnsStatic Fallback
getString(rc, key)string''
getBoolean(rc, key)booleanfalse
getNumber(rc, key)number0
getValue(rc, key)ValueStatic value
getAll(rc)Record<string, Value>All known keys
getKeysByPrefix(rc, prefix)string[]Empty array

Typed getters fall back to defaultConfig when the remote value cannot be converted. Firebase offers this behavior only in its Android SDK.

Lifecycle Methods

MethodDescription
initializeApp({ apiKey }) + getRemoteConfig(app)Modular setup, same shape as firebase/remote-config.
rc.defaultConfigIn-app defaults object, served until a fetch activates and for missing keys.
rc.settingsminimumFetchIntervalMillis (default 12h) and fetch timeout.
setCustomSignals(rc, signals)Set app-supplied key/value pairs for targeting. Signals merge, and null removes a key. Max 100 signals.
fetchConfig(rc, interval?) / activate(rc) / fetchAndActivate(rc)Same functions as Firebase. The optional interval argument overrides the window for one call.
ensureInitialized(rc) / isSupported() / setLogLevel(rc, level)Identical to their Firebase counterparts.
rc.lastFetchStatus / rc.fetchTimeMillisFetch metadata.

Custom Signals

Custom signals let you target config values based on app-specific data. Unlike Firebase, signals never leave the device because evaluation is local.

Kotlin
val signals = CustomSignals.Builder()
    .put("player_level", 42L)
    .put("subscription_tier", "gold")
    .build()
// suspend function, call from a coroutine
AppSpikeRemoteConfig.setCustomSignals(signals)
Swift
try await AppSpike.remoteConfig().setCustomSignals([
    "player_level": 42,
    "subscription_tier": "gold",
])
Kotlin — commonMain
val signals = CustomSignals.Builder()
    .put("player_level", 42L)
    .put("subscription_tier", "gold")
    .build()
// suspend function, call from a coroutine
AppSpikeRemoteConfig.setCustomSignals(signals)
Dart
await remoteConfig.setCustomSignals({
  'player_level': 42,
  'subscription_tier': 'gold',
});
TypeScript
await remoteConfig().setCustomSignals({ player_level: 42, subscription_tier: 'gold' });
C#
await remoteConfig.SetCustomSignalsAsync(new CustomSignals.Builder()
    .Put("player_level", 42L)
    .Put("subscription_tier", "gold")
    .Build());
TypeScript
await setCustomSignals(remoteConfig, { player_level: 42, subscription_tier: 'gold' });

Value Types

Four types: string, boolean, number, json. Type is fixed once a parameter is published, so changing it requires delete + recreate. JSON has no dedicated accessor on Android: read with getString(key) and parse with your own tooling (same as Firebase). On iOS, JSON parameters decode directly to Codable types via the subscript API.

Targeting

Targeting Conditions

Conditions are named, reusable predicates. Each condition is a list of clauses combined with AND. For each parameter, the first matching condition (top-down) wins, same as Firebase.

Attribute Description Operators
App Target specific apps within your org in not_in
Platform iOS or Android == !=
App version Semver comparison == != > >= < <=
Country ISO-3166 alpha-2, resolved from IP in not_in
Language BCP-47, prefix matching (en matches en-US) in not_in
Percentage rollout Stable percentage rollout (deterministic bucketing) <= > between
Custom signal App-supplied key/value targeting Numeric, string, regex, version
Date / time window Time window targeting <= >
First open time Install cohort targeting <= >
Device ID Specific device targeting (up to 50 IDs) in not_in

Percentage Rollouts

Each device is bucketed deterministically by SHA-256 of device ID + seed, with 4-decimal precision. Clauses that share a seed name divide the same set of users, so you can build groups that never overlap for controlled experiments. between 0 and 50 and between 50 and 100 on the same seed never overlap. A device keeps its bucket across fetches.

Limits

LimitValue
Parameters per template3,000
Conditions per template2,000
Custom signals per device100
Parameter key length256 chars
Template value text1,000,000 chars