Expo Recipe (Universal Push)
Two ways to push an Expo app with Native Notify — the native-notify SDK on the Expo path, or universal push with the native APNs/FCM token from expo-notifications.
Expo apps have two supported routes:
- The Expo SDK path — start here. Install
native-notifyand callregisterNNPushToken(); the SDK registers Expo push tokens, and sends go through Expo's push service with receipts, inboxes and analytics. Follow Installation and Setup. - Universal push — register the native APNs/FCM token yourself. Choose this when you want sends to go directly through your own Firebase project and Apple key (no Expo push service in the middle).
Universal push in an Expo app
Get the native device token with expo-notifications:
import * as Notifications from "expo-notifications";
import { Platform } from "react-native";
export async function registerUniversalDevice({ appId, appToken, subscriberId }) {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== "granted") return null;
// The NATIVE token: APNs on iOS, FCM on Android. Development/EAS builds
// only — Expo Go cannot mint native tokens (Android, SDK 53+).
const devicePushToken = await Notifications.getDevicePushTokenAsync();
// A key that survives re-launches. On iOS use expo-application's
// getIosIdForVendorAsync(), on Android getAndroidId(), or any UUID you
// persist in secure storage.
const deviceId = await stableDeviceId();
const tokens =
Platform.OS === "ios"
? { apnsToken: String(devicePushToken.data) }
: { fcmToken: String(devicePushToken.data) };
const res = await fetch("https://app.nativenotify.com/api/universal/device/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
appId,
appToken,
deviceId,
platform: Platform.OS,
subscriberId, // omit for a mass (all-users) device
tokens,
}),
});
return res.json(); // { ok, device, tokens }
}
That is the entire integration: the same call registers on every launch (idempotent), the same deviceId re-registers a rotated token, and the app's push credentials are what make sends deliver.
Expo Go:
getDevicePushTokenAsync() needs a development or EAS build. Expo Go cannot mint push tokens on Android (SDK 53+) and never exposes native tokens on iOS.
Which route should we choose?
| You want… | Route |
|---|---|
| The fastest Expo setup, Notification Inbox components, receipts, analytics app-opens | Expo SDK path — native-notify + registerNNPushToken() |
| Sends straight through your own Firebase/Apple credentials, one contract shared with Flutter/native apps | Universal push — this page |
| Both features in different apps | Both — the paths are independent per app |
Next steps
- Device Registration — every field and rule.
- Verify Delivery — test-send to the device you just registered.
- Send Notifications — blasts, device lists, subscriber lists.