rn-push-notifications — guardrail for push + local notifications
For the current Expo API and per-version details, verify against the Expo docs / MCP
mcp.expo.dev/expo/skills(see rn-fundamentals → Source of truth).
The 5 rules (non-negotiable)
expo-notificationsis the SDK. Don't pull@react-native-firebase/messagingdirectly — Expo wraps APNs+FCM. Bare FCM is needed only for the rare case where you ship without Expo.- Request permission AT THE RIGHT MOMENT, not at app launch. Wait for a clear opt-in trigger (signup complete, settings screen, feature first use).
- Setup
setNotificationHandlerat module level inapp/_layout.tsx, ONCE. Not inside any component. - Handle the 3 entry paths: foreground (
addNotificationReceivedListener), tapped while alive (addNotificationResponseReceivedListener), tapped on cold start (getLastNotificationResponseAsync). - Token storage: send the Expo push token to YOUR backend via authenticated HTTPS POST. Never store the raw token in AsyncStorage — use
expo-secure-storeor treat it as server-owned.
Quick decision tree
- "Expo push service or direct APNs/FCM?" →
references/decision-tree.md - "How do I wire up the handlers + deep linking?" →
references/patterns.md - "What's the app.json / config plugin setup?" →
references/setup.md
Common anti-patterns (NEVER do)
- ❌
Notifications.requestPermissionsAsync()inapp/_layout.tsxon first render — bad UX (denied permanently if user says no by mistake). - ❌
setNotificationHandlerinside a screen component — runs on every mount, last one wins. - ❌ Sending the Expo push token over plain HTTP — token = ability to spam the user.
- ❌ Reading
notification.request.content.datawithout type-narrowing — runtime error on malformed payload. - ❌ Forgetting
getLastNotificationResponseAsyncon cold start — deep link from tapped notification gets lost. - ❌ Storing badge count in client state only — server is source of truth; client subtracts on read.
Sources
- Course: codewithbeto.dev/rnCourse — "Push Notifications" module (1 lesson free, rest paid).
- Official: https://docs.expo.dev/push-notifications/overview/
- Official: https://docs.expo.dev/versions/latest/sdk/notifications/