Hai dịch vụ native cần biết:
- APNs (Apple Push Notification service): iOS push.
- FCM (Firebase Cloud Messaging): Android push, có thể proxy iOS qua APNs.
Option 1 — Direct (@react-native-firebase/messaging + APNs):
- Setup phức tạp: cần Firebase project, push cert/auth key APNs, token registration.
- Mạnh: toàn quyền kiểm soát, không phụ thuộc Expo; FCM miễn phí.
- Code (modular API, bản namespaced messaging() đã deprecated):
import {
getMessaging, getToken, onMessage, setBackgroundMessageHandler,
} from '@react-native-firebase/messaging'
const messaging = getMessaging()
const token = await getToken(messaging) // gửi lên backend
onMessage(messaging, async (msg) => console.log('foreground', msg))
// đăng ký ở index.js, ngoài component
setBackgroundMessageHandler(messaging, async (msg) => console.log('background', msg))Option 2 — Expo Notifications (recommend cho Expo project):
- Wrapper hoàn chỉnh quanh APNs + FCM.
- API thống nhất, không cần care platform khác biệt.
- Có thể dùng Expo push service (FCM/APNs proxy) miễn phí, hoặc dùng FCM/APNs trực tiếp.
import * as Notifications from 'expo-notifications'
const { status } = await Notifications.requestPermissionsAsync()
const token = (await Notifications.getExpoPushTokenAsync({ projectId })).data
// Gửi token lên backend, backend gọi Expo push API hoặc FCM
Notifications.addNotificationReceivedListener((notification) => console.log(notification))
Notifications.addNotificationResponseReceivedListener((response) => {
// user tap notification → navigate vào screen
})Lưu ý:
- iOS: cần aps-environment entitlement (development cho dev build, production cho TestFlight/App Store).
- Android 13+: cần permission POST_NOTIFICATIONS runtime.
- Foreground vs background handler khác nhau — test cả hai trạng thái, và cả trường hợp app đã bị tắt hẳn (killed).
- Từ Expo SDK 53, Expo Go trên Android không còn nhận push — phải dùng development build.
- Token có thể expire (user reinstall app) — backend phải handle invalid token error gracefully.