
Expo 通知实战expo-notifications 推送落地、状态矩阵与深度链接【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expoExpo 通知基于expo-notifications模块在 React Native 项目内同时覆盖 Android 与 iOS 的本地通知和远程推送。本文给出一套可落地的实践路径从依赖安装、app.json插件配置、权限请求、Expo 推送令牌获取到 FCM 与 APNs 凭据配置、EAS Build 构建、前/后台与关闭状态的行为控制以及基于data字段的深度链接。能力边界本地通知与远程推送的差异expo-notifications把两套能力装进同一套 API本地通知由应用进程自行调度依赖expo-notify之外的定时或事件触发不需要推送令牌应用被系统终止后无法继续投递。远程推送消息从服务端经 FCM 或 APNs 下发到设备应用可以不在前台甚至处于关闭状态需要 Expo 推送令牌ExponentPushToken[...]格式作为投递地址。应用不同状态下的行为差异状态矩阵应用状态AndroidiOS前台系统横幅 触发addNotificationReceivedListener默认无横幅、无声音仅触发addNotificationReceivedListenersetNotificationHandler可开启横幅与声音后台系统横幅 通知中心系统横幅 通知中心已关闭系统投递到通知中心点击触发addNotificationResponseReceivedListener系统直接投递到锁屏与通知中心点击后冷启动应用并触发响应监听器统一 API 覆盖了setNotificationHandler、requestPermissionsAsync、getExpoPushTokenAsync、setNotificationChannelAsync等调用上层代码无需区分平台只有凭据准备和渠道行为仍需按平台处理。跑通第一条推送通知依赖安装、插件配置与最小代码在一个现成的 Expo 应用里先用以下命令补齐三个依赖npx expo install expo-notifications expo-device expo-constantsexpo-notifications负责通知的注册、调度与展示expo-device用于区分真机与模拟器expo-constants用来读取projectId。接着在app.json的expo.plugins中加入expo-notificationsprebuild 时原生侧的通知配置会被自动写入不需要手工改AndroidManifest.xml或 iOS 的Entitlements文件。最小可运行的注册与发送逻辑如下包含权限请求、Expo 推送令牌获取、监听器和通过 Expo 推送接口发送测试消息import { useEffect, useState } from react; import { View, Text, Button } from react-native; import * as Device from expo-device; import * as Notifications from expo-notifications; import Constants from expo-constants; Notifications.setNotificationHandler({ handleNotification: async () ({ shouldShowBanner: true, shouldShowList: true, shouldPlaySound: true, shouldSetBadge: true, }), }); async function getToken() { const { status } await Notifications.getPermissionsAsync(); if (status ! granted) { const r await Notifications.requestPermissionsAsync(); if (r.status ! granted) return null; } const projectId Constants.expoConfig?.extra?.eas?.projectId ?? Constants.easConfig?.projectId; const token await Notifications.getExpoPushTokenAsync({ projectId }); return token.data; } async function send(token) { await fetch(https://exp.host/--/api/v2/push/send, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ to: token, title: 测试标题, body: 来自 Expo 推送的第一条通知, data: { screen: home }, }), }); } export default function App() { const [token, setToken] useState(); const [last, setLast] useState(null); useEffect(() { if (!Device.isDevice) return; getToken().then(setToken); const onReceive Notifications.addNotificationReceivedListener( (n) setLast(n) ); const onTap Notifications.addNotificationResponseReceivedListener( (r) console.log(clicked, r) ); return () { onReceive.remove(); onTap.remove(); }; }, []); return ( View style{{ flex: 1, justifyContent: center, padding: 24 }} Text{token}/Text Text{last?.request.content.body}/Text Button title发送测试通知 onPress{() send(token)} disabled{!token} / /View ); }验证方式在真机上运行应用确认界面打印出ExponentPushToken[...]随后点按按钮触发发送。前台会走handleNotification逻辑弹出横幅把应用切到后台再发送则走系统横幅与通知中心。生产部署FCM 与 APNs 凭据配置和 EAS Build 构建Android 侧走 Firebase Cloud Messaging先在 Firebase 控制台创建项目拿到google-services.json再通过eas credentials把该文件上传为项目的 Android 凭据。构建脚本参考 FCM 凭据官方配置文档。iOS 侧走 APNs在 Apple Developer 账号下为应用标识开启 Push Notifications导出.p8格式的 APNs 密钥同样通过eas credentials配置为项目的 iOS 凭据或写入eas.json的构建配置中。两侧凭据就绪后执行eas build生成包含原生推送配置的应用包。需要注意两个限制Expo 推送令牌只能在真机上获取模拟器不产生有效令牌推送通道的完整验证前后台投递、锁屏展示也必须在真机完成模拟器上不会收到远程推送。通知生命周期从发起到点击监听器与深度链接按时间线拆解一次推送的完整过程发起服务端POST到https://exp.host/--/api/v2/push/sendpayload 至少包含to推送令牌、title、body可选sound、badge与自定义data对象。到达前台系统把消息交给应用Notifications.setNotificationHandler返回的布尔值决定shouldShowBanner、shouldShowList、shouldPlaySound、shouldSetBadge同时addNotificationReceivedListener回调参数notification.request.content包含title、body、data。后台/关闭系统直接渲染横幅或锁屏通知JS 侧不执行任何代码用户点击后addNotificationResponseReceivedListener被触发应用已运行或先冷启动再触发。点击响应响应对象的notification.request.content.data携带发起时写入的自定义数据是深度链接的入口Notifications.addNotificationResponseReceivedListener((response) { const { screen, id } response.notification.request.content.data ?? {}; if (screen) router.navigate(screen, { id }); });应用从杀死状态被点击拉起时getLastNotificationResponseAsync会返回最近一次点击的通知用它可以在冷启动路径上恢复同样的页面跳转。排错清单通知不显示、令牌失败与渠道问题通知不显示原因系统级通知开关关闭、权限状态非granted、Android 渠道未创建或发送请求实际返回了错误。 解决核对系统设置与getPermissionsAsync返回值在 Android 上先执行setNotificationChannelAsync打印fetch响应体确认推送接口返回data: []而非错误对象。令牌获取失败原因在模拟器上调用getExpoPushTokenAsync或未传入正确的projectId。 解决确认Device.isDevice为true再执行注册流程projectId从Constants.expoConfig?.extra?.eas?.projectId或Constants.easConfig?.projectId读取两者都缺失时检查eas.json与app.json的关联配置。Android 通知不震动或静默送达原因渠道的AndroidImportance设置过低或根本未创建渠道。 解决显式调用setNotificationChannelAsync并设置importance如MAX必要时配置vibrationPattern与lightColorAndroid 8.0 及以上所有通知都必须归属某个渠道。iOS 始终收不到远程推送原因APNs 证书未配置、证书与应用签名 Bundle ID 不一致。 解决重新核对eas credentials中上传的 APNs 密钥确认其对应的 App ID 与构建包签名完全一致。点击通知无法跳转到目标页原因data字段未写入或冷启动路径未处理。 解决发送时始终携带data冷启动分支里补一次getLastNotificationResponseAsync检查。参考文档更完整的平台差异、凭据细节与边界情况见 推送通知设置文档、接收通知文档 与 推送通知 FAQ。【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考