Install
npx expo install expo-notifications expo-device1. Register for a push token
Ask permission, then get the Expo push token. Store it on your backend keyed to the user:
// npx expo install expo-notifications expo-device
import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';
async function registerForPush() {
if (!Device.isDevice) return null; // no push on simulators
const { status: existing } = await Notifications.getPermissionsAsync();
let status = existing;
if (existing !== 'granted') {
status = (await Notifications.requestPermissionsAsync()).status;
}
if (status !== 'granted') return null;
const token = (await Notifications.getExpoPushTokenAsync()).data;
return token; // send this to YOUR backend and store it per user
}2. Send a notification
From your server, POST to the Expo push endpoint:
// From your server — POST to Expo's push service.
async function sendPush(expoPushToken, title, body) {
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
to: expoPushToken,
title,
body,
data: { screen: 'Inbox' }, // read this on tap to deep-link
}),
});
}3. Handle the tap
Listen for the response and deep-link using the notification’s data:
import { useEffect } from 'react';
import * as Notifications from 'expo-notifications';
function useNotificationTaps(onOpen) {
useEffect(() => {
const sub = Notifications.addNotificationResponseReceivedListener((response) => {
const data = response.notification.request.content.data;
onOpen(data); // e.g. navigate to data.screen
});
return () => sub.remove();
}, [onOpen]);
}Key APIs
| Prop | Type | Default | Description |
|---|---|---|---|
| getExpoPushTokenAsync | fn | — | Returns the token you send to your backend. |
| requestPermissionsAsync | fn | — | Prompts for notification permission. |
| addNotificationResponseReceivedListener | fn | — | Fires when the user taps a notification. |
| data | object | — | Custom payload — use it to route the tap. |
Gotchas
- Push doesn’t work on simulators/emulators — test on a real device.
- iOS needs a real dev/production build with push entitlements. Expo Go can’t receive remote push on iOS.
- The Expo push token isn’t the same as the native FCM/APNs token. Send the
ExponentPushToken[...]value to the Expo service. - Store the token per user and refresh it — tokens can change on reinstall or restore.
FAQ
How do I set up push notifications in Expo? Install expo-notifications, register for a token, store it on your backend, and POST to exp.host/--/api/v2/push/send to send.
Why aren’t my notifications arriving? Most often: testing on a simulator, using Expo Go on iOS, or sending the wrong token. Use a device + dev build + the Expo push token.