操指南:從權(quán)限到點(diǎn)擊回傳)
Expo 推送通知實(shí)操指南從權(quán)限到點(diǎn)擊回傳【免費(fèi)下載鏈接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ex/expoExpo 的expo-notifications庫為 React Native 應(yīng)用提供跨平臺(tái)推送通知方案它封裝了 Android 的 FCM 與 iOS 的 APNs讓你用一套 API 收發(fā)通知。想給 App 加一條提醒不必自己對(duì)接推送服務(wù)裝好庫、拿到令牌就能發(fā)出第一條測(cè)試推送。環(huán)境準(zhǔn)備npx expo install expo-notifications expo-constantsexpo-notifications負(fù)責(zé)權(quán)限、令牌和事件監(jiān)聽expo-constants負(fù)責(zé)讀取項(xiàng)目配置里的projectId。再在app.json的plugins數(shù)組中加入expo-notifications插件會(huì)自動(dòng)寫入兩端所需的原生配置。讓最小推送跑起來權(quán)限、令牌與測(cè)試發(fā)送在拿推送令牌ExpoPushToken相當(dāng)于設(shè)備在 Expo 推送服務(wù)里的唯一地址之前必須完成兩件事拿到用戶授權(quán)、找到項(xiàng)目projectId。倉庫里的示例 apps/notification-tester/src/registerForNotifications.ts 就是這個(gè)流程的完整實(shí)現(xiàn)核心邏輯如下import Constants from expo-constants; import { getPermissionsAsync, requestPermissionsAsync, getExpoPushTokenAsync } from expo-notifications; async function registerForPushNotificationsAsync() { let { status } await getPermissionsAsync(); if (status ! granted) { ({ status } await requestPermissionsAsync()); } if (status ! granted) { throw new Error(notification permission denied); } const projectId Constants.expoConfig?.extra?.eas?.projectId ?? Constants.easConfig?.projectId; const token (await getExpoPushTokenAsync({ projectId })).data; return token; }應(yīng)用啟動(dòng)后在useEffect里調(diào)用它把令牌顯示在界面上方便測(cè)試。注意令牌必須綁定projectId生成兩端配置里的 projectId 不一致會(huì)導(dǎo)致后續(xù)發(fā)送被拒。發(fā)送測(cè)試通知只需要向 Expo 推送服務(wù)發(fā)一個(gè) POST 請(qǐng)求無需自建服務(wù)端await fetch(https://exp.host/--/api/v2/push/send, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ to: expoPushToken, title: Original Title, body: And here is the body!, data: { someData: goes here }, }), });data是自定義數(shù)據(jù)字段后續(xù)可以從通知對(duì)象里原樣讀回是實(shí)現(xiàn)深度鏈接的入口。生產(chǎn)環(huán)境要把令牌上傳到你自己的后端并入庫而不是只存在 App 本地。平臺(tái)差異補(bǔ)齊Android 渠道與 iOS 憑據(jù)Android 8.0 起通知必須掛在渠道channel通知的分類容器下不建渠道推送可能不顯示。在注冊(cè)前調(diào)用setNotificationChannelAsync創(chuàng)建默認(rèn)渠道if (Platform.OS android) { await Notifications.setNotificationChannelAsync(default, { name: default, importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: #FF231F7C, }); }憑據(jù)兩端也各不相同Android 需要 FCM v1 憑據(jù)google-services.jsoniOS 需要 APNs 密鑰通常通過eas credentials上傳到 EAS 項(xiàng)目構(gòu)建時(shí)自動(dòng)寫入。另外兩點(diǎn)容易忽略Android 上令牌可能隨系統(tǒng)重啟或配置變更而更新用addPushTokenListener監(jiān)聽新令牌并回傳后端。iOS 上用戶拒絕權(quán)限彈窗后無法再發(fā)推送denied狀態(tài)要單獨(dú)處理引導(dǎo)用戶去系統(tǒng)設(shè)置里手動(dòng)開啟。getDevicePushTokenAsync返回的是直連 FCM/APNs 的原始設(shè)備令牌走 Expo 推送服務(wù)時(shí)請(qǐng)用ExpoPushToken兩者不通用。前臺(tái)行為控制一個(gè) Handler 與兩個(gè)監(jiān)聽器App 在前臺(tái)時(shí)通知默認(rèn)不彈橫幅展示行為由setNotificationHandler決定Notifications.setNotificationHandler({ handleNotification: async () ({ shouldShowBanner: true, shouldShowList: true, shouldPlaySound: false, shouldSetBadge: true, }), });兩個(gè)監(jiān)聽器分工不同addNotificationReceivedListener只在前臺(tái)收到通知時(shí)觸發(fā)addNotificationResponseReceivedListener在用戶點(diǎn)擊通知時(shí)觸發(fā)且前后臺(tái)、冷啟動(dòng)都有效const received Notifications.addNotificationReceivedListener(n { console.log(received, n.request.content.data); }); const response Notifications.addNotificationResponseReceivedListener(r { const data r.notification.request.content.data; if (data?.screen) { navigation.navigate(data.screen); } }); return () { received.remove(); response.remove(); };完整的事件對(duì)象結(jié)構(gòu)和監(jiān)聽器寫法可參考文檔 docs/pages/push-notifications/receiving-notifications.mdx。批量發(fā)送與送達(dá)確認(rèn)不想寫服務(wù)端代碼時(shí)可用 Expo 賬號(hào)控制臺(tái)里的 Notifications 工具直接向指定令牌發(fā)推送。接口本身支持一次提交最多 100 條消息數(shù)組只要屬于同一個(gè)項(xiàng)目能顯著減少請(qǐng)求次數(shù)。發(fā)送后服務(wù)會(huì)先返回 push ticket接收憑證真正投遞到 FCM/APNs 之后可再查 push receipt送達(dá)回執(zhí)確認(rèn)結(jié)果?;貓?zhí)約 15 分鐘后可用24 小時(shí)后清除。如果回執(zhí)里出現(xiàn)DeviceNotRegistered說明設(shè)備已卸載或關(guān)閉權(quán)限應(yīng)停止向該令牌發(fā)送直到用戶重新注冊(cè)。?? 踩坑排錯(cuò)五類常見現(xiàn)象令牌為空、注冊(cè)失敗 → 模擬器缺少 Google Play 服務(wù) → 換物理設(shè)備或給 Android 模擬器裝上 Play 服務(wù)。發(fā)送返回 400 →to不是有效令牌或 payload 里的 projectId 與令牌不匹配 → 確認(rèn)令牌由當(dāng)前項(xiàng)目的 projectId 生成。前臺(tái)收到通知卻不彈橫幅 → handler 默認(rèn)不展示 → 用setNotificationHandler顯式聲明shouldShowBanner: true。Android 通知不顯示 → 8.0 未創(chuàng)建通知渠道 → 先setNotificationChannelAsync建渠道再發(fā)推送。發(fā)送看似成功但設(shè)備收不到 → 憑據(jù)未配置或過期 → 檢查 EAS 項(xiàng)目里的 FCM/APNs 憑據(jù)并重新構(gòu)建。收尾整條鏈路可以濃縮成三件事權(quán)限是門檻令牌是地址監(jiān)聽器是回傳。把這三件跑通后自定義聲音、角標(biāo)和深度鏈接都是在此基礎(chǔ)上疊加。更多細(xì)節(jié)見官方文檔 docs/pages/push-notifications/庫源碼在 packages/expo-notifications/?!久赓M(fèi)下載鏈接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ex/expo創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考