expo run, or EAS development builds. Expo Go is not supported because Expo Go cannot load custom native modules that are not already built into the Expo Go app.
Use this guide for Expo projects. If your React Native app already owns native android and ios projects without Expo prebuild, use React Native Bare SDK.
What The Expo Plugin Does
The Sendrealm Expo plugin updates native project configuration during prebuild. It can:- Copy
google-services.jsoninto the Android app during prebuild. - Set default Android notification icon and color metadata.
- Configure iOS APNs environment.
- Add iOS background remote notification mode.
- Add an iOS Notification Service Extension for rich image notifications.
- Point the iOS project at a local native Sendrealm pod during SDK development.
Setup Order
Follow this order:- Upload Firebase and APNs credentials in Sendrealm.
- Install
@sendrealm/react-native. - Add the Expo plugin to
app.jsonorapp.config.js. - Add Android
google-services.jsonand configure iOS push capabilities. - Run Expo prebuild or create an EAS development build.
- Initialize Sendrealm from JavaScript.
- Request notification permission after your app explains the value.
- Link the device with
loginafter user sign-in. - Send test pushes on Android and iOS.
Requirements
- Expo project using development builds or prebuild
- 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 for the iOS Bundle ID in Apple Developer
Install
Configure The Plugin
Add the Sendrealm plugin toapp.json or app.config.js:
extra values are available to your JavaScript app through Expo config. Do not put Sendrealm API keys or provider private keys in extra. The Sendrealm app ID is safe client configuration; Firebase service account JSON and APNs .p8 keys are server/provider credentials and belong in the Sendrealm dashboard.
Generate google-services.json For Expo Android
Expo Android builds still need Firebase Android app configuration. Generate google-services.json from Firebase:
- Open the Firebase console.
- Select the Firebase project for your Android app.
- If you only have a Google Cloud project, add Firebase to that existing Google Cloud project from the Firebase console first.
- From the Firebase project overview, click the Android icon or Add app.
- Enter the Android package name from your Expo config. This is usually
expo.android.package, for examplecom.example.app. - Click Register app.
- Click Download google-services.json.
- Save it in your Expo project, commonly at:
google-services.json for that build profile.
Plugin Options Explained
| Option | What it does |
|---|---|
android.googleServicesFile | Path to your Firebase google-services.json; copied to android/app/google-services.json during prebuild. |
android.notificationIcon | Sets the default Android drawable resource name for notifications. |
android.notificationColor | Sets the default Android notification accent color. |
ios.apnsEnvironment | Selects sandbox for development builds or production for production-signed builds. |
ios.enableBackgroundRemoteNotifications | Adds iOS remote-notification background mode for silent/background pushes. |
ios.notificationServiceExtension | Creates a Sendrealm Notification Service Extension for rich image notifications. |
ios.sendrealmIOSPodPath | Points iOS at a local native Sendrealm pod for SDK repository development. |
iOS Capabilities With Expo
Expo does not remove the Apple push requirements. Your Expo app still builds into a native iOS app with a Bundle ID, App ID, entitlements, and provisioning profile. In Apple Developer:- Open Certificates, Identifiers & Profiles.
- Open Identifiers.
- Select the App ID for the Bundle ID in your Expo config, usually
expo.ios.bundleIdentifier. - Enable Push Notifications.
- Save the App ID changes.
- Set
ios.apnsEnvironmenttosandboxfor development builds orproductionfor TestFlight and App Store builds. - Set
ios.enableBackgroundRemoteNotificationstotrueonly if you send silent/background pushes. - Set
ios.notificationServiceExtensiontotrueif you send rich image notifications.
ios project, open ios/*.xcworkspace in Xcode and verify the main app target has Push Notifications under Signing & Capabilities. If you use silent pushes, also verify Background Modes includes Remote notifications. If you use rich images, verify the Notification Service Extension target exists.
iOS APNs Key For Sendrealm
Sendrealm sends iOS pushes through APNs, so the Sendrealm dashboard needs an APNs private key even when your app is built with Expo. Create the key in Apple Developer:- Open Certificates, Identifiers & Profiles.
- Open Keys.
- Create a new key with a clear name, for example
Sendrealm Push. - Select Apple Push Notification service.
- Configure the APNs key scope if Apple asks for one.
- Confirm and download the
.p8file immediately.
expo.ios.bundleIdentifier. A key for another Apple service cannot send push notifications.
Upload the .p8 file, Key ID, Team ID, Bundle ID, and APNs environment in Sendrealm. Expo/EAS signing credentials and Sendrealm APNs provider credentials are related to the same app, but they are not the same thing: EAS signs the app, while Sendrealm uses the APNs key to send notifications.
See Mobile Push Credentials for the full APNs key walkthrough.
Prebuild And Run Locally
Generate native projects and run locally:--device for iOS push testing because APNs testing should happen on a physical device.
Build With EAS
Build development clients with EAS:Initialize
Read values from Expo config and initialize once:apnsEnvironment to production for TestFlight and App Store builds. A common pattern is to read this from build-time config so development builds use sandbox and production builds use production.
Ask For Permission
Request notification permission after your app explains the value:Identity, Tags, And Events
Link the device after login:login before setting user tags. Use events for behavior that should drive segmentation, analytics, or automations.
Rich iOS Media
Rich image notifications require a Notification Service Extension. Enable it in the plugin:Android Notification Icons
Android status bar icons should be simple drawable resources, usually monochrome. If you set:res/drawable/ic_stat_sendrealm.xml. If the icon is missing, Android may fall back to the app icon or a default icon.
Delivery Timing And OS Behavior
Expo development builds use the same native delivery rules as any other Android or iOS app. Sendrealm can register the device and send the notification, but the device OS decides when and how the notification is delivered or displayed. Notifications may not be instant when:- Android is in Doze or App Standby.
- The Android message is normal priority.
- Android battery optimization or OEM background rules restrict the app.
- iOS treats the payload as a background update.
- APNs or iOS throttles low-priority/background delivery.
- The device is offline or has poor network connectivity.
- The user disabled notifications or a notification channel.
- Focus mode or notification summary defers iOS alerts.
Diagnostics
Use support diagnostics when testing development builds:- Expected API URL
- Device ID
- Token presence
- Permission status
- Subscribed state
- SDK version
- Empty or shrinking queue counts
- No unexpected last SDK error
Testing Checklist
Before releasing:- The app is a development build or production build, not Expo Go.
- Android test device has Google Play services.
- iOS test device is physical.
- Plugin options are committed and prebuild has been rerun.
- Firebase package name matches the Android app.
- iOS App ID has Push Notifications enabled in Apple Developer.
- iOS native target has Push Notifications enabled after prebuild.
- APNs Bundle ID, Team ID, Key ID,
.p8, and environment match the iOS build. initializeresolves successfully.requestPermissionreturns the expected permission state.- A foreground push arrives.
- A background push arrives.
- Non-urgent pushes still make sense if delivery is delayed.
- Time-sensitive pushes use visible notification payloads.
- Notification tap opens the expected screen or URL.
- Rich media works if
notificationServiceExtensionis enabled.
Troubleshooting
| Symptom | What to check |
|---|---|
| Expo Go does not work | Build a development client because custom native code is required. |
| Android token is missing | Use a Google Play device or emulator and verify the Firebase Android package name. |
| iOS push does not arrive | Use a physical device and verify APNs environment, Bundle ID, Team ID, Key ID, and .p8 key in Sendrealm. |
| iOS entitlement is missing | Enable Push Notifications on the Apple Developer App ID, rerun prebuild, and rebuild the app. |
| Silent pushes do not wake the app reliably | Set ios.enableBackgroundRemoteNotifications to true, rebuild, and treat silent delivery as best effort. |
| Notifications are delayed | Check Android power management, FCM priority, iOS APNs priority, Focus settings, and notification permissions. |
| Some pushes are missing | Check stale tokens, disabled channels, background-only payloads, excessive pending messages, and provider diagnostics. |
| Rich images do not attach | Confirm notificationServiceExtension is enabled and prebuild has been rerun. |
| Plugin changes do not appear | Rerun expo prebuild. If generated native files are stale, regenerate them intentionally. |
Tags return ContactNotLinked | Call login(userId, email) before tags. |