你需要了解的通知

编辑页面

在开始之前,了解通知类型及其行为。


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

通知是向用户传达新信息或事件的提醒,即使应用当前并未 सक्रिय使用。通知的适用范围很广,不同平台之间的差异也会让实现通知变得令人望而生畏。

无论你是刚开始接触通知,还是已经有一定了解,本文都会解释不同类型通知及其行为。

Expo 的通知支持建立在 Android 和 iOS 提供的原生功能之上。原生平台中的相同概念和行为同样适用于 Expo 应用。如果你不确定某个具体的通知功能,请参阅各个平台的 官方文档

远程通知和本地通知

  1. 推送通知:(也称为“远程通知”)从远程服务器发送到用户设备的通知。
  2. 本地通知:(也称为“应用内通知”)在应用内部创建并显示的通知。由于许多创建这些通知的 API 会在特定时间创建它们,因此它们有时也被称为“定时通知”。

expo-notifications 同时支持推送通知和本地通知。由于该能力并未内置到 Expo Go 中,你必须使用 开发构建 才能使用推送通知。

有关如何创建并显示本地通知,请参见 应用内通知。本指南的其余部分聚焦于推送通知。

推送通知的送达

当推送通知到达你的应用时,其行为取决于应用状态和通知类型。先来明确一下术语:

应用状态

  • 前台:应用正在前台 सक्रिय运行。其界面当前显示在屏幕上。
  • 后台:应用在后台运行,处于“最小化”状态。其界面当前未显示在屏幕上。
  • 已终止:应用已被“杀死”,通常是通过应用切换器中的滑走手势。在 Android 上,如果用户在设备设置中强制停止应用,它必须被手动重新打开后,通知才会开始生效(这是 Android 的限制)。

推送通知行为

对于任何类型的通知,当应用处于前台时,应用可以控制传入通知的处理方式。应用可以直接展示它,显示某些自定义应用内 UI,或者甚至忽略它(这由 NotificationHandler 控制)。当应用不在前台时,行为取决于通知类型。

下表总结了推送通知送达设备时会发生什么:

通知类型应用在前台时应用在后台时应用已终止时
通知消息带数据负载的通知消息送达会运行 NotificationReceivedListenerJS 任务OS 显示通知OS 显示通知
无头后台通知送达会运行 NotificationReceivedListenerJS 任务送达会运行 JS 任务送达会运行 JS 任务

当用户与通知交互时(例如按下某个操作按钮),以下处理器会对你可用。

应用状态触发的 iOS 监听器触发的 Android 监听器
前台NotificationResponseReceivedListenerNotificationResponseReceivedListener
后台NotificationResponseReceivedListenerNotificationResponseReceivedListenerJS 任务
已终止NotificationResponseReceivedListenerJS 任务

在上表中,每当触发 NotificationResponseReceivedListener 时,useLastNotificationResponse 的返回值也会随之变化。

当应用未运行或已被杀死,并且通过点击通知启动时,请尽早在 iOS 上注册 NotificationResponseReceivedListener(在模块顶层)。为了在应用启动后处理初始通知响应,我们建议在启动期间同时检查 useLastNotificationResponsegetLastNotificationResponse,而不是仅依赖监听器。这同样也是让应用进入前台的操作按钮的推荐做法。

推送通知类型

通知消息

通知消息是一种指定展示信息的通知,例如标题或正文文本。

  • 在 Android 上,这对应于包含 AndroidNotification 的推送通知请求
  • 在 iOS 上,这对应于包含 aps.alert 字典apns-push-type 头设置为 alert 的推送通知请求。

当你使用 Expo Push Service,并指定 titlesubtitlebodyiconchannelId 时,生成的推送通知请求就是通知消息。

通知消息的典型用途是让它立即展示给用户,而无需额外处理。

带数据负载的通知消息

这是一个仅适用于 Android 的术语(参见官方文档),指推送通知请求同时包含 data 字段和 notification 字段。

在 iOS 上,额外数据可以作为常规通知消息请求的一部分。Apple 不区分带数据和不带数据的通知消息。

无头后台通知

无头通知是一种远程通知,它不直接指定标题或正文文本等展示信息。除了下面的例外*之外,无头通知不会展示给用户。相反,它们携带的数据(JSON)会由应用中通过 registerTaskAsync 定义的 JavaScript 任务进行处理。该任务可以执行任意逻辑。例如,写入 AsyncStorage、发起 api 请求,或基于推送通知的数据展示一个本地通知。

我们使用“无头后台通知”这一术语来指代 Android 上的 数据消息 和 iOS 上的 后台通知。它们的关键相似点是:这两种通知类型都只允许发送 JSON 数据,并由应用进行后台处理。

无头后台通知即使在应用已终止时,也能在收到通知后运行自定义 JavaScript。这很强大,但也有一个限制:即使通知已经送达设备,OS 也不能保证它一定送达到你的应用。这可能由多种原因导致,例如在 Android 上启用了 Doze 模式,或者你发送了过多的后台通知——Apple 建议不要 每小时发送超过两到三条

当你使用 Expo Push Service,并且只指定 data_contentAvailable: true(以及其他非交互字段,例如 ttl)时,生成的推送通知请求会产生无头后台通知。

要在 iOS 上使用无头后台通知,你必须先对其进行 配置

如果你不需要在后台运行 JavaScript,那么经验法则是优先使用常规的通知消息。

* 例外情况是,当你在 data 中指定 titlemessage 时。在这种情况下,expo-notifications 包会自动在 Android 上展示无头通知,但在 iOS 上不会。我们计划在未来的版本中使这种行为在各个平台上更加一致。

仅数据通知

Android 有 数据消息 的概念。iOS 并没有完全相同的概念,但一个接近的等价物是 无头后台通知

你也可能会遇到“静默通知”这个术语,它是另一种指代不会向用户展示任何内容的通知的名称——我们将其描述为 无头后台通知

外部参考

以下是 Android 和 iOS 推送通知官方资源的不完整列表: