Expo Push Notifications

Send device push notifications with Expo: permissions, push tokens, backend storage, and the iOS credentials you still need.

This guide covers adding device push notifications to an Expo app using Expo's push notification service, and where it still needs real iOS credentials underneath.

Quick Answer

Request notification permission, use expo-notifications to get an Expo push token (which needs a valid EAS project ID), send that token to your backend and store it against the signed-in user, then send notifications from your server through the Expo push API; for iOS, also upload an APNs key to your EAS project.

1. Request Permission

Ask for notification permission at a sensible point in the flow, not on cold first launch before the user has context. Required on iOS; recommended (and required from Android 13+) on Android.

2. Get an Expo Push Token

const token = await Notifications.getExpoPushTokenAsync({
  projectId: 'your-eas-project-id',
});

The projectId must match a real project in EAS; without it, token retrieval fails or returns undefined, which is the most common first bug people hit.

3. Store the Token on Your Backend

Send the token to your server and associate it with the currently signed-in user. Tokens rotate over time (reinstalls, OS updates, etc.), so re-register on each app launch/sign-in rather than assuming a token is permanent.

4. iOS Still Needs APNs Credentials

Expo's push service is a convenience layer on top of the platforms' own push systems; it does not remove the need for real iOS credentials. Generate an APNs authentication key in your Apple Developer account and upload it to your EAS project (eas credentials), or notifications will never actually arrive on iOS even though tokens register successfully.

5. Send from Your Backend

await fetch('https://exp.host/--/api/v2/push/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    to: expoPushToken,
    title: 'Order update',
    body: 'Your order is on the way.',
  }),
});

6. The iOS Simulator Cannot Receive Push

Test push notifications on a real iOS device. The simulator cannot register for real push tokens, so a "nothing happens" result there doesn't indicate a bug.

Common Issues

getExpoPushTokenAsync fails or returns nothing the EAS projectId is missing or doesn't match a real project.

Token registers but nothing arrives on iOS no APNs key uploaded to the EAS project; this is the most common iOS push issue and produces no client-side error.

Nothing happens on the iOS simulator expected; test on a physical device.

Notifications worked, then silently stopped for a specific user their stored token likely rotated (reinstall, restore) and the backend still has the old one; re-register tokens on each sign-in.

Notification received in background, does nothing in foreground foreground and background/killed notification handling are separate code paths; confirm the foreground handler is implemented.

Verification Checklist

  • the app requests and receives notification permission;
  • a valid Expo push token is retrieved (project ID is set correctly);
  • the token is sent to and stored by the backend, tied to the user;
  • an APNs key is uploaded to the EAS project (iOS);
  • a test notification sent from the backend arrives on a real device, not just the simulator;
  • foreground, background, and killed app states are all handled.

Next Steps