General
Plugin throws "You are trying to setup RetenoSDK without any props"
The plugin requires a configuration object. You can configure only the platform you need.
[
"expo-reteno-sdk",
{
"ios": {
"sdkAccessToken": "...",
"mode": "production",
"notificationService": "apns",
"appGroups": ["group.com.your.bundleid.reteno-local-storage"]
},
"android": {
"sdkAccessToken": "..."
}
}
]Runtime initialization options are ignored
If sdkAccessToken is set in the platform plugin config, the SDK initializes automatically before JavaScript runs. A later Reteno.initialize() call is a no-op.
isDebugMode can be enabled in Path A without switching to JavaScript initialization — use config.isDebugMode in the plugin config alongside sdkAccessToken:
{
"android": { "sdkAccessToken": "YOUR_KEY", "config": { "isDebugMode": true } },
"ios": { "sdkAccessToken": "YOUR_KEY", "config": { "isDebugMode": true }, "mode": "...", "notificationService": "...", "appGroups": ["..."] }
}To apply lifecycleTrackingOptions, sessionDurationSeconds, pauseInAppMessages, or iosDeviceTokenHandlingMode, remove sdkAccessToken from that platform's plugin config, run npx expo prebuild --clean, and initialize from JavaScript:
await Reteno.initialize({
apiKey: 'YOUR_SDK_ACCESS_KEY',
lifecycleTrackingOptions: 'ALL',
sessionDurationSeconds: 30,
});Plugin changes not applied after updating SDK or plugin props
If native code does not reflect your latest app.json config after updating expo-reteno-sdk, run prebuild with --clean to regenerate native projects from scratch:
npx expo prebuild --cleanThis removes ios/ and android/ folders and recreates them. Make sure any manual native changes are backed up or managed via config plugins.
SDK does not work in Expo Go
expo-reteno-sdk uses native modules and cannot run in Expo Go. Use development build or bare workflow.
npx expo run:ios
# or
npx expo run:androidiOS
EAS Build fails on iOS extension signing/provisioning
If cloud build fails for NotificationServiceExtension / NotificationContentExtension, add extra.eas.build.experimental.ios.appExtensions to Expo config (for both targets).
See setup section:
Expo/SetupGuide/IOS.md-> EAS Build (important for iOS extensions)
Expo references:
Build fails: Missing required mode key
mode keymode is required in iOS plugin config:
"ios": {
"mode": "production",
"notificationService": "apns",
"appGroups": ["group.com.your.bundleid.reteno-local-storage"]
}Use development for debug/simulator, production for TestFlight/App Store.
See SetupGuide for the full list of required and optional props.
Push notifications or in-app messages do not work
If sdkAccessToken is omitted from the iOS plugin config, call Reteno.initialize({ apiKey: '...' }) once at app startup before registering listeners.
Push notifications not received on device
- Enable Push Notifications capability in Xcode.
- Verify
modematches current build type. - Ensure
Reteno.registerForRemoteNotifications()is called at app startup.
NotificationServiceExtension already exists warning
NotificationServiceExtension already exists warningNotificationServiceExtension already exists in project. Skipping... during prebuild is expected if extension already exists.
Development Team not set, code signing fails
Set devTeam with your Apple Team ID:
"ios": {
"devTeam": "XXXXXXXXXX"
}Firebase on iOS: build errors with modular headers
If using notificationService: "firebase", run:
cd ios && pod install --repo-updatesetDeviceToken on Android
setDeviceToken on AndroidIn v2.0.0, setDeviceToken is a no-op on Android and resolves successfully. Android token handling is performed by the native Firebase messaging service.
Android
Plugin skips build.gradle configuration (Kotlin DSL warning)
build.gradle configuration (Kotlin DSL warning)Kotlin DSL (.gradle.kts) is not fully supported. The plugin prints a console warning and skips dependency and Google Services plugin injection. However, compileOptions injection still runs unconditionally — it checks for existing sourceCompatibility/targetCompatibility in the android {} block, but if they are absent it injects Groovy-syntax lines into .gradle.kts, which will break the build.
The following are still configured automatically even with Kotlin DSL:
AndroidManifest.xml—ExpoRetenoClickReceiver,ExpoRetenoPushReceiver, andRetenoMessagingService(FCM)gradle.properties—android.useAndroidX
The following require manual setup:
1. Google Services classpath — project-level build.gradle.kts:
buildscript {
dependencies {
classpath("com.google.gms:google-services:4.4.4")
}
}2. Reteno dependencies — app-level build.gradle.kts:
plugins {
id("com.google.gms.google-services")
}
dependencies {
implementation("com.reteno:core:2.9.4")
implementation("com.reteno:push:2.9.4")
implementation("com.reteno:fcm:2.9.4")
implementation("com.google.firebase:firebase-messaging:23.1.0")
implementation("com.google.firebase:firebase-messaging-ktx:23.1.0")
}3. Compile options — inside the android {} block in app-level build.gradle.kts. Verify these are present; add them if missing:
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}Build fails: minSdkVersion too low
minSdkVersion too lowReteno Android SDK requires minSdkVersion 26.
{
"expo": {
"android": {
"minSdkVersion": 26
}
}
}Push notifications not received on Android
- Verify
google-services.jsonis located atandroid/app/google-services.json. - Ensure
Reteno.registerForRemoteNotifications()is called. - Verify the automatic
sdkAccessTokenor theapiKeypassed toReteno.initialize().
Push events not tracked on Android after upgrading to v2.0.0
v2.0.0 adds an updated FCM messaging service and manifest configuration. Regenerate the native project after upgrading:
npx expo prebuild --cleanThis regenerates the native Android project with the updated manifest configuration.
