React NativeExamples · Props · Code

Expo Push Notifications

Push in Expo is three steps: register the device for a push token, send a message to Expo’s push service from your backend, and handle the tap. Here’s each, with the gotchas that waste the most time.

Install

npx expo install expo-notifications expo-device

1. 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

PropTypeDefaultDescription
getExpoPushTokenAsyncfnReturns the token you send to your backend.
requestPermissionsAsyncfnPrompts for notification permission.
addNotificationResponseReceivedListenerfnFires when the user taps a notification.
dataobjectCustom 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.

Related components

Skip the boilerplate

Describe your screen in ShipNative and it wires up the component for you — in a real, exportable React Native app.

Generate it with AI →