Skip to main content
The Sendrealm React Native SDK gives your JavaScript app one API for mobile push, while using native Android and iOS code under the hood. On Android it wraps the Sendrealm Android SDK and Firebase Cloud Messaging. On iOS it wraps the Sendrealm iOS APNs module. Use this page for React Native apps that own their native android and ios projects. If you use Expo prebuild or EAS development builds, use React Native Expo SDK.

Mental Model

React Native push has two layers:
  • The JavaScript layer calls Sendrealm.initialize, requestPermission, login, trackEvent, and listener APIs.
  • The native layer receives FCM or APNs tokens, handles notification callbacks, displays notifications, and forwards events back to JavaScript.
Both layers matter. If JavaScript initializes correctly but the iOS app delegate does not forward APNs tokens, Sendrealm cannot send iOS push. If Android Firebase credentials do not match the package name, the native Android layer may never receive a valid FCM token.

Setup Order

Follow this order:
  1. Upload Firebase and APNs credentials in Sendrealm.
  2. Install @sendrealm/react-native.
  3. Add Android google-services.json and enable iOS Push Notifications capabilities.
  4. Rebuild Android and iOS native apps.
  5. Add the iOS app delegate hooks.
  6. Initialize Sendrealm from JavaScript.
  7. Request notification permission after your app explains the value.
  8. Call login when the user signs in.
  9. Send test pushes on Android and iOS.

Requirements

  • React 18 or newer
  • React Native 0.72 or newer
  • Android device or emulator with Google Play services
  • Physical iOS device for APNs testing
  • A Sendrealm app ID from the dashboard
  • Firebase credentials uploaded for Android delivery
  • APNs credentials uploaded for iOS delivery
  • Push Notifications enabled on the iOS Apple Developer App ID and Xcode target
Expo Go is not supported because the SDK includes custom native code. Use an Expo development build or bare React Native app instead.

Install

Install the package:
npm install @sendrealm/react-native
Rebuild the native apps so React Native links the native module:
npx react-native run-android
npx react-native run-ios
If your iOS project uses CocoaPods directly, install pods after adding the package:
cd ios
pod install
Installing the npm package is not enough by itself. Because this SDK contains native code, Android and iOS must be rebuilt before the native module is available.

Android Setup

Android push uses Firebase Cloud Messaging. Before testing Android:
  • The device or emulator must have Google Play services.
  • The Firebase Android app package name must match your React Native Android applicationId.
  • google-services.json must be added to the native Android app.
  • The Firebase service account JSON must be uploaded in Sendrealm.
  • The app must be rebuilt after installing the SDK.
The SDK contributes the required Android manifest entries, including internet access, Android 13 notification permission, a Firebase messaging service, and a notification action receiver.

Generate google-services.json

Create or download the file from Firebase:
  1. Open the Firebase console.
  2. Select the Firebase project for your Android app.
  3. If you only have a Google Cloud project, add Firebase to that existing Google Cloud project from the Firebase console first.
  4. From the Firebase project overview, click the Android icon or Add app.
  5. Enter the exact package name from android/app/build.gradle, usually defaultConfig.applicationId.
  6. Click Register app.
  7. Click Download google-services.json.
  8. Move the file to:
android/app/google-services.json
Make sure the filename is exactly google-services.json, not google-services (1).json.

Apply The Google Services Gradle Plugin

React Native bare apps are native Android projects, so the Firebase config file still needs the Google Services Gradle plugin. In android/build.gradle or the root Gradle plugins block, make sure the plugin is available:
plugins {
    id("com.google.gms.google-services") version "4.5.0" apply false
}
In android/app/build.gradle, apply it to the app module:
plugins {
    id("com.android.application")
    id("com.google.gms.google-services")
}
Some React Native projects use Groovy Gradle files instead of Kotlin Gradle files. The same plugin still needs to be added; use the syntax that matches your project.

Do Not Confuse The Two Firebase JSON Files

React Native Android setup uses both files:
  • android/app/google-services.json in the app so Firebase client configuration is available.
  • Firebase service account private key JSON in Sendrealm so Sendrealm can send through FCM.
They are not interchangeable.

iOS AppDelegate Setup

iOS push uses APNs. iOS delivers APNs tokens through app delegate callbacks, so your app must forward those callbacks to Sendrealm. Add the Sendrealm React Native import and configure the module:
import SendrealmReactNative

func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
  SendrealmModule.configure()
  return true
}
Forward the APNs device token:
func application(
  _ application: UIApplication,
  didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
  SendrealmModule.didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
}
Forward remote notifications for background and silent push handling:
func application(
  _ application: UIApplication,
  didReceiveRemoteNotification userInfo: [AnyHashable: Any],
  fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
  SendrealmModule.didReceiveRemoteNotification(userInfo)
  completionHandler(.newData)
}
Use apnsEnvironment: "sandbox" for development builds and apnsEnvironment: "production" for TestFlight or App Store builds.

iOS Capabilities In Xcode

Bare React Native apps have a real native iOS project, so iOS push setup is the same as a native Swift app. The JavaScript package cannot add Apple signing capabilities by itself. In Xcode:
  1. Open ios/<YourApp>.xcworkspace.
  2. Select the iOS app project in the left navigator.
  3. Select the main app target.
  4. Open Signing & Capabilities.
  5. Click the add capability button.
  6. Add Push Notifications.
  7. Confirm the Team and Bundle Identifier match the app you configured in Apple Developer and Sendrealm.
In Apple Developer, the matching App ID must also have Push Notifications enabled. If the App ID capability changes, refresh automatic signing or regenerate the provisioning profile before testing on device. If your React Native app uses silent pushes or background updates, add Background Modes to the same app target and check Remote notifications. This is required for background remote notification handling, but it does not make background delivery guaranteed. iOS still decides when background work is allowed. If your app sends rich image notifications, add a Notification Service Extension target or use the Sendrealm native extension setup your project supports. Rich media will not attach unless the extension is built into the app.

iOS APNs Key For Sendrealm

Sendrealm needs an APNs private key uploaded in the dashboard before it can send to your React Native iOS app. Create the key in Apple Developer with these requirements:
  • The Apple Developer user must be an Account Holder or Admin.
  • The key must have Apple Push Notification service selected.
  • If Apple asks for scope, use Team Scoped for the simplest setup or Topic Specific for a stricter key.
  • If you choose Topic Specific, include the exact Bundle ID used by the React Native iOS target.
  • Download the .p8 file immediately because Apple only allows the private key to be downloaded once.
Upload the .p8 file, Key ID, Team ID, Bundle ID, and APNs environment in Sendrealm. Use sandbox for development builds installed from Xcode and production for TestFlight or App Store builds. See Mobile Push Credentials for the full step-by-step APNs key walkthrough.

Initialize

Initialize once near app startup:
import { useEffect } from "react";
import Sendrealm from "@sendrealm/react-native";

export default function App() {
  useEffect(() => {
    void Sendrealm.initialize({
      appId: "YOUR_SENDREALM_APP_ID",
      autoRequestPermission: false,
      apnsEnvironment: "sandbox",
    });
  }, []);

  return null;
}
Initialization creates or restores a Sendrealm device ID, registers the native push token, stores identity and subscription state, and enables notification event tracking.

Initialization Options

Common options:
  • appId: required Sendrealm app ID from the dashboard.
  • externalUserId: optional user ID to link during initialization.
  • userEmail: optional user email to link during initialization.
  • autoRequestPermission: whether the SDK should ask for notification permission during initialization.
  • apnsEnvironment: iOS APNs environment, usually sandbox for development and production for TestFlight or App Store.
  • suppressForegroundNotifications: lets JavaScript handle foreground display instead of native display.
  • foregroundPresentation: controls foreground display behavior.
Most apps should keep autoRequestPermission: false and ask permission later.

Notification Permission

Ask for permission after your app explains the value:
await Sendrealm.requestPermission();
Read the current status:
const status = await Sendrealm.getPermissionStatus();
const allowed = await Sendrealm.hasNotificationPermission();
Android 13 and newer show a runtime notification prompt. Android 12 and older do not have a runtime prompt, but notifications can still be disabled in system settings. iOS prompts for alert, badge, and sound authorization.

Identity

Call login after the user signs in:
await Sendrealm.login("user-123", "user@example.com");
This links the current app install to a Sendrealm contact. Call logout when the user signs out:
await Sendrealm.logout();
If your app supports account switching, call login each time the active account changes.

Tags

Tags are app-sourced attributes. Use them for preferences, state, and behavior observed by the app:
await Sendrealm.addTags({
  plan: "pro",
  onboardingComplete: true,
});
Good tag examples:
  • plan: "pro"
  • preferredLanguage: "en"
  • onboardingComplete: true
  • lastViewedCategory: "orders"
Do not use SDK tags for authoritative account, billing, compliance, security, or verified profile data. Send those from your backend through server-side APIs.
Tags require the device to be linked to a contact. Call login before adding user tags.

Custom Events

Track custom events when the app observes behavior that should be available in Sendrealm:
await Sendrealm.trackEvent("checkout_started", {
  product_id: "sku_123",
  price: 29,
});
Use stable lowercase names. Good examples include app_opened, checkout_started, lesson_completed, and order_viewed.

Notification Listeners

Use listeners when JavaScript needs to react to push activity while the app is running. Listen for notification opens:
const sub = Sendrealm.addNotificationClickListener((event) => {
  console.log(event.notificationId, event.launchUrl);
});

sub.remove();
Listen for foreground notifications:
const sub = Sendrealm.addForegroundNotificationListener((event) => {
  console.log(event.payload.notification?.title);
});
Read the notification that opened the app from a cold start:
const initial = await Sendrealm.getInitialNotification();
Call getInitialNotification soon after app startup. Cold-start open data is most useful before your navigation tree has already decided where to route the user.

Foreground Display

Control foreground display after initialization:
await Sendrealm.setForegroundPresentation({
  display: true,
  banner: true,
  list: true,
  sound: true,
  badge: true,
});
Use suppressForegroundNotifications: true during initialization if JavaScript will render its own in-app notification UI instead of letting the native SDK display the notification.

Android Notification Channels

Android channels control notification importance, sound, vibration, and visibility. Create a channel when your app needs explicit channel behavior:
await Sendrealm.createNotificationChannel({
  id: "orders",
  name: "Orders",
  importance: "high",
  soundName: "order_update",
});

await Sendrealm.syncNotificationChannels();
Dashboard-created channels are synced automatically on initialization, token refresh, and app resume. Android remembers channel behavior after a channel is created. If you need a different sound or importance, use a new channel ID.

Delivery Timing And OS Behavior

React Native apps still depend on native Android and iOS push behavior. The JavaScript API gives you one Sendrealm interface, but the final delivery and display rules come from Firebase Cloud Messaging, APNs, Android, and iOS. Notifications may be delayed, dropped, throttled, collapsed, or hidden when:
  • Android devices enter Doze or App Standby.
  • Android battery optimization or OEM background limits restrict the app.
  • Android notification channels are disabled or set to low importance.
  • FCM normal-priority messages wait for a maintenance window.
  • FCM lowers behavior after high priority is overused for non-visible messages.
  • iOS background updates are throttled by APNs or iOS.
  • iOS Focus, notification summary, or notification settings suppress display.
  • The device is offline or the token is stale.
Use push for timely communication, but do not design critical app state to exist only inside a notification. The app should be able to fetch the current state when opened, even if a push arrived late or did not display.

Diagnostics

Collect support-safe diagnostics during setup:
const diagnostics = await Sendrealm.getSupportDiagnostics();
console.log(JSON.stringify(diagnostics, null, 2));
Support diagnostics redact tokens, secrets, authorization headers, cookies, and raw payloads by default. Look for:
  • Device ID is present.
  • Token is present.
  • Permission is granted or has the expected status.
  • Subscribed state is true unless the user opted out.
  • Queue counts are empty or shrinking.
  • Last SDK error is empty or explains the failure.

Testing Checklist

Before releasing:
  • Android test device has Google Play services.
  • iOS test device is physical.
  • Android package name matches Firebase.
  • iOS App ID has Push Notifications enabled in Apple Developer.
  • iOS app target has Push Notifications enabled in Xcode.
  • iOS Bundle ID, Team ID, Key ID, .p8, and APNs environment match the build.
  • The app rebuilds successfully after installing the SDK.
  • iOS app delegate forwards APNs callbacks.
  • initialize resolves successfully.
  • requestPermission returns the expected permission state.
  • A foreground push is received.
  • A background push is received.
  • Delayed delivery is acceptable for non-urgent campaigns.
  • Time-sensitive notifications use visible platform-appropriate payloads.
  • Tapping a push routes to the expected screen.
  • getSupportDiagnostics() shows token presence.

Troubleshooting

SymptomWhat to check
Expo Go fails to load the packageUse a development build or bare app because custom native code is required.
Android token is nullUse a Google Play device or emulator and verify Firebase package name setup.
iOS signing fails after enabling pushRefresh automatic signing or regenerate the provisioning profile for the App ID.
iOS push entitlement is missingEnable Push Notifications in both Apple Developer and the Xcode app target.
Silent pushes do not wake the app reliablyConfirm Background Modes, Remote notifications is enabled and treat silent delivery as best effort.
Notifications are delayedCheck Android Doze/App Standby, FCM priority, iOS APNs priority, Focus settings, and user notification settings.
Some pushes are missingCheck stale tokens, disabled notification channels, excessive pending messages, background-only payloads, and provider diagnostics.
Tags return ContactNotLinkedCall login(userId, email) before tags.
Notification opens app but not URLCheck metadata.androidLaunchUrl, metadata.iosLaunchUrl, and native deep link configuration.