Expo 通知功能实战:3 个环节跑通你的第一条推送通知
2026/8/30 9:19:53 网站建设 项目流程

Expo 通知功能实战:3 个环节跑通你的第一条推送通知

【免费下载链接】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

写过通知代码却收不到推送?权限弹窗被拒、令牌拿到手是 undefined、应用划走之后消息石沉大海——这些是刚接触推送时最容易栽进去的坑。Expo 通知功能(expo-notifications 模块)把 Android 和 iOS 的推送差异封装成一套 JS 接口:你只管请求权限、拿到 Expo 推送令牌(可以理解成这台设备的"收件地址")、调 Expo Push API 发消息,前台怎么展示则交给一段你自己写的策略代码。

能力速览:它能帮你干什么

  • 把消息精准送到某台设备:用推送令牌 + Expo Push API,用户把应用划走后消息照样送达,系统负责弹出横幅。
  • 前台行为完全由你定夺:应用开着时收到推送,是弹系统横幅、静默写日志,还是只刷新你自己的界面,都靠setNotificationHandler一句话拍板。
  • 接住用户的点击:用户点通知、点按钮,都会触发响应监听器,你拿到的data字段可以直接用来做深度链接跳转。
  • 本地定时通知也能顺手做:不经过服务器,应用内就能创建一次性或周期性的本地通知。

动手接入:从装包到收到第一条推送

前置:装两个包,并确认你是用 Development Build

npx expo install expo-notifications expo-constants

expo-notifications是核心模块,expo-constants用来读取项目里的projectId。这里有个容易忽略的前提:Expo Go 里用不了推送,必须走 EAS 构建出 Development Build(eas build),然后在真机上测。Android 带 Google Play 服务的模拟器也可以,iOS 用 Xcode 14+ 的模拟器。

关键配置:app.json 里加一行插件

{ "expo": { "plugins": ["expo-notifications"] } }

这一行让 config-plugins 在生成原生工程时自动配好默认通知图标等原生细节,省得你去改 AndroidManifest 或 iOS 工程文件。

请求权限,拿到 Expo 推送令牌

先查、再申请,别上来就弹系统权限框(用户之前可能已经给过,重复弹窗很减好感):

const { status } = await Notifications.getPermissionsAsync(); const finalStatus = status === 'granted' ? status : (await Notifications.requestPermissionsAsync()).status; const projectId = Constants.expoConfig?.extra?.eas?.projectId; const token = (await Notifications.getExpoPushTokenAsync({ projectId })).data;

权限没拿到就早退并提示用户去系统设置里开;projectId缺失时getExpoPushTokenAsync会直接报错,这是"令牌为 undefined"最常见的原因。

发出第一条推送

拿到令牌后,一条 POST 请求就够了:

await fetch('https://exp.host/--/api/v2/push/send', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ to: token, title: 'Hello Expo', body: '这是你的第一条推送', data: { screen: 'home' }, }), });

不想手搓请求的话,官方通知工具页面(expo.dev 的 Notifications 页)可以粘贴令牌直接发测试推送,适合第一遍联调。

机制拆解:一条推送在三种状态下的走向

推送到了设备之后,谁来接管取决于应用当时在不在前台:

服务器 → Expo Push API → 设备系统 ├─ 前台:JS 监听器 + 你的 handler 决定展示与否 └─ 后台/已杀:系统横幅 → 用户点击 → 响应监听器
  • 前台:应用是"主人",推送先进你的 JS。setNotificationHandler里四个返回值(shouldShowBanner/shouldPlaySound/shouldSetBadge/shouldShowList)控制横幅、声音、角标和是否进通知列表。想让前台只静默更新数据?把shouldShowBanner设成false即可。
  • 后台:系统直接弹横幅,你的代码不参与展示;用户点击后,addNotificationResponseReceivedListener被触发,response.notification.request.content.data就是发送时塞进去的data
  • 已杀(用户手动清掉应用):iOS 上点通知会冷启动应用。稳妥做法是在模块顶层就注册响应监听器,启动时再补查一次getLastNotificationResponse,别只依赖监听器,否则冷启动的第一次点击可能拿不到。

避坑与调优:群里最常问的 3 个问题

Q:推送明明发了,手机毫无反应?先别怀疑代码。九成是构建方式问题:Expo Go 里没有推送能力,必须 Development Build;再查 EAS 里该项目的推送凭据(iOS 的 APNs、Android 的 FCM)是否配全。两者都确认过,再用通知工具重发一次,设备端日志里能看到接收过程。

Q:Android 上通知能弹,但没声音、没震动?Android 8.0+ 的通知挂在"渠道"上,默认渠道的重要性偏低。启动时用setNotificationChannelAsync显式建一个渠道,importance给到AndroidImportance.MAX并设置振动模式,声音震动就都正常了。

Q:权限被拒之后,应用里再也拿不到令牌?被拒不等于永久失败。先getPermissionsAsync判断状态,只有denied才弹申请;如果弹完还是拒,引导用户去系统设置手动开启,而不是反复弹框。

下一步

试着把本地定时通知(scheduleNotificationAsync)也接上,推送 + 本地两种能力就齐了。细节可以翻 推送通知配置文档,遇到怪问题先看 官方 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询