你需要了解的通知
编辑页面
在开始之前,了解通知类型及其行为。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
通知是向用户传达新信息或事件的提醒,即使应用当前并未 सक्रिय使用。通知的适用范围很广,不同平台之间的差异也会让实现通知变得令人望而生畏。
无论你是刚开始接触通知,还是已经有一定了解,本文都会解释不同类型通知及其行为。
Expo 的通知支持建立在 Android 和 iOS 提供的原生功能之上。原生平台中的相同概念和行为同样适用于 Expo 应用。如果你不确定某个具体的通知功能,请参阅各个平台的 官方文档。
远程通知和本地通知
- 推送通知:(也称为“远程通知”)从远程服务器发送到用户设备的通知。
- 本地通知:(也称为“应用内通知”)在应用内部创建并显示的通知。由于许多创建这些通知的 API 会在特定时间创建它们,因此它们有时也被称为“定时通知”。
expo-notifications 同时支持推送通知和本地通知。由于该能力并未内置到 Expo Go 中,你必须使用 开发构建 才能使用推送通知。
有关如何创建并显示本地通知,请参见 应用内通知。本指南的其余部分聚焦于推送通知。
推送通知的送达
当推送通知到达你的应用时,其行为取决于应用状态和通知类型。先来明确一下术语:
应用状态
- 前台:应用正在前台 सक्रिय运行。其界面当前显示在屏幕上。
- 后台:应用在后台运行,处于“最小化”状态。其界面当前未显示在屏幕上。
- 已终止:应用已被“杀死”,通常是通过应用切换器中的滑走手势。在 Android 上,如果用户在设备设置中强制停止应用,它必须被手动重新打开后,通知才会开始生效(这是 Android 的限制)。
推送通知行为
对于任何类型的通知,当应用处于前台时,应用可以控制传入通知的处理方式。应用可以直接展示它,显示某些自定义应用内 UI,或者甚至忽略它(这由 NotificationHandler 控制)。当应用不在前台时,行为取决于通知类型。
下表总结了推送通知送达设备时会发生什么:
| 通知类型 | 应用在前台时 | 应用在后台时 | 应用已终止时 |
|---|---|---|---|
| 通知消息 和 带数据负载的通知消息 | 送达会运行 NotificationReceivedListener 和 JS 任务 | OS 显示通知 | OS 显示通知 |
| 无头后台通知 | 送达会运行 NotificationReceivedListener 和 JS 任务 | 送达会运行 JS 任务 | 送达会运行 JS 任务 |
当用户与通知交互时(例如按下某个操作按钮),以下处理器会对你可用。
| 应用状态 | 触发的 iOS 监听器 | 触发的 Android 监听器 |
|---|---|---|
| 前台 | NotificationResponseReceivedListener | NotificationResponseReceivedListener |
| 后台 | NotificationResponseReceivedListener | NotificationResponseReceivedListener 和 JS 任务 |
| 已终止 | NotificationResponseReceivedListener | JS 任务 |
在上表中,每当触发 NotificationResponseReceivedListener 时,useLastNotificationResponse 的返回值也会随之变化。
当应用未运行或已被杀死,并且通过点击通知启动时,请尽早在 iOS 上注册NotificationResponseReceivedListener(在模块顶层)。为了在应用启动后处理初始通知响应,我们建议在启动期间同时检查useLastNotificationResponse或getLastNotificationResponse,而不是仅依赖监听器。这同样也是让应用进入前台的操作按钮的推荐做法。
推送通知类型
通知消息
通知消息是一种指定展示信息的通知,例如标题或正文文本。
- 在 Android 上,这对应于包含
AndroidNotification的推送通知请求 - 在 iOS 上,这对应于包含
aps.alert字典 且apns-push-type头设置为alert的推送通知请求。
当你使用 Expo Push Service,并指定 title、subtitle、body、icon 或 channelId 时,生成的推送通知请求就是通知消息。
通知消息的典型用途是让它立即展示给用户,而无需额外处理。
带数据负载的通知消息
这是一个仅适用于 Android 的术语(参见官方文档),指推送通知请求同时包含 data 字段和 notification 字段。
在 iOS 上,额外数据可以作为常规通知消息请求的一部分。Apple 不区分带数据和不带数据的通知消息。
无头后台通知
无头通知是一种远程通知,它不直接指定标题或正文文本等展示信息。除了下面的例外*之外,无头通知不会展示给用户。相反,它们携带的数据(JSON)会由应用中通过 registerTaskAsync 定义的 JavaScript 任务进行处理。该任务可以执行任意逻辑。例如,写入 AsyncStorage、发起 api 请求,或基于推送通知的数据展示一个本地通知。
无头后台通知即使在应用已终止时,也能在收到通知后运行自定义 JavaScript。这很强大,但也有一个限制:即使通知已经送达设备,OS 也不能保证它一定送达到你的应用。这可能由多种原因导致,例如在 Android 上启用了 Doze 模式,或者你发送了过多的后台通知——Apple 建议不要 每小时发送超过两到三条。
当你使用 Expo Push Service,并且只指定 data 和 _contentAvailable: true(以及其他非交互字段,例如 ttl)时,生成的推送通知请求会产生无头后台通知。
要在 iOS 上使用无头后台通知,你必须先对其进行 配置。
如果你不需要在后台运行 JavaScript,那么经验法则是优先使用常规的通知消息。
* 例外情况是,当你在 data 中指定 title 或 message 时。在这种情况下,expo-notifications 包会自动在 Android 上展示无头通知,但在 iOS 上不会。我们计划在未来的版本中使这种行为在各个平台上更加一致。
仅数据通知
Android 有 数据消息 的概念。iOS 并没有完全相同的概念,但一个接近的等价物是 无头后台通知。
你也可能会遇到“静默通知”这个术语,它是另一种指代不会向用户展示任何内容的通知的名称——我们将其描述为 无头后台通知。
外部参考
以下是 Android 和 iOS 推送通知官方资源的不完整列表: