Skip to main content
The AppDNA React Native SDK is designed to work seamlessly offline. All offline logic — event queuing, config caching, and retry — is delegated to the native iOS and Android SDKs. The TypeScript layer does not manage any offline state directly.

Architecture

The React Native SDK is a thin wrapper around the native SDKs via NativeModules. When your app is offline:
  • Events are queued in native persistent storage
  • Cached configuration is served from the native layer
  • Queued events are flushed automatically when connectivity is restored
The Promise-based API works seamlessly regardless of network state. Calls resolve based on the native layer’s handling — cached data is returned when available, and events are silently queued for later delivery.
You do not need to add any offline-handling code in your React Native layer. The native SDKs manage all caching, queuing, and retry logic automatically.

Config Priority

The SDK resolves configuration values using the following priority order:
PrioritySourceDescription
1RemoteFreshly fetched from the AppDNA server
2CachedPreviously fetched config stored on device
3BundledShipped with the app as a fallback
When the device is offline, the SDK falls back to the cached config. If no cached config exists (e.g., first launch while offline), the bundled config is used.

Configuration Options

Control offline behavior through AppDNAOptions when configuring the SDK:
await AppDNA.configure("adn_live_xxx", "production", {
  flushInterval: 30,  // Seconds between automatic event flushes
  batchSize: 20,      // Number of events to batch before flushing
  configTTL: 300,     // Seconds before cached config is considered stale
});
ParameterTypeDefaultDescription
flushIntervalnumber30Seconds between automatic event flushes
batchSizenumber20Number of events to batch before flushing
configTTLnumber300Seconds before cached config is considered stale
These values are passed to the native SDK during configuration. Adjusting them does not change any JavaScript-level behavior — all batching and caching is handled natively.

Bundled Config

For true offline-first support on first launch, you can bundle a default configuration with your app. This ensures the SDK has a valid config even if the device has never connected to the AppDNA server.

iOS

Add the bundled config file to your Xcode project:
  1. Create a file named appdna-config.json with your default configuration.
  2. Add it to your Xcode project by dragging it into the project navigator.
  3. Ensure it is included in the Copy Bundle Resources build phase of your target.

Android

Place the bundled config file in the Android assets directory:
android/app/src/main/assets/appdna-config.json
The bundled config is a static fallback and will not receive updates. It is only used when no cached or remote config is available. Keep it in sync with your server configuration to avoid inconsistencies on first launch.

Event Queue Behavior

Events tracked while offline are stored in a persistent native queue:
  1. Events are added to the queue when AppDNA.track(...) is called.
  2. The native SDK attempts to flush the queue every flushInterval seconds.
  3. If the flush fails (no connectivity), events remain in the queue.
  4. When connectivity is restored, the queue is flushed automatically.
  5. Calling AppDNA.flush() forces an immediate flush attempt.
The queue has no hard size limit. Events are persisted to disk, so they survive app restarts and device reboots.
Events are delivered in order. The SDK guarantees that events queued while offline are sent in the same order they were tracked, preserving the correct event timeline.

Lifecycle Handling

The native SDKs manage app lifecycle transitions automatically:
EventBehavior
App backgroundedQueued events are flushed immediately
App terminatedEvent queue is persisted to disk
App foregroundedConfig is refreshed if TTL has expired
App cold startPending events from the previous session are flushed
Event listeners registered via the React Native layer (e.g., onEntitlementsChanged, onPushReceived) survive app backgrounding. The native layer maintains the listener registrations and re-emits events when the app returns to the foreground.

Unsubscribe Pattern

All event listeners in the React Native SDK return a cleanup function. Always call the cleanup function when the listener is no longer needed:
// Subscribe
const unsubscribe = AppDNA.billing.onEntitlementsChanged((entitlements) => {
  console.log("Entitlements changed:", entitlements);
});

// Unsubscribe when component unmounts
unsubscribe();
This pattern applies to all listeners across the SDK:
ListenerReturns
AppDNA.billing.onEntitlementsChanged() => void
AppDNA.onWebEntitlementChanged() => void
AppDNAPush.onPushReceived() => void
AppDNAPush.onPushTapped() => void
Failing to call the unsubscribe function will result in memory leaks and stale callbacks. In React components, always clean up in the useEffect return function.

React Hook Pattern

import { useEffect, useState } from 'react';
import { AppDNA } from '@appdna/react-native-sdk';

function useEntitlements() {
  const [entitlements, setEntitlements] = useState([]);

  useEffect(() => {
    // Load initial entitlements
    AppDNA.billing.getEntitlements().then(setEntitlements);

    // Listen for changes
    const unsubscribe = AppDNA.billing.onEntitlementsChanged(setEntitlements);

    // Clean up on unmount
    return () => unsubscribe();
  }, []);

  return entitlements;
}

Network Resilience Summary

ScenarioSDK Behavior
No network on first launchBundled config is used; events are queued
Network lost mid-sessionCached config continues; events are queued
Network restoredConfig refreshed if stale; queued events flushed
Intermittent connectivityAutomatic retry with exponential backoff
App killed while offlineEvents persisted to disk; sent on next launch
The React Native SDK provides fully offline-capable behavior with zero additional code. Configure flushInterval, batchSize, and configTTL to tune performance, and optionally bundle a default config for first-launch scenarios.