你需要了解的有关通知的信息

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


通知具有很大的表面积,并且不同平台之间的差异会使实现通知变得令人生畏。

¥Notifications have a large surface area and differences across platforms can make implementing notifications intimidating.

无论你是从通知开始还是已有知识,本文档旨在通过解释你应该了解的不同通知类型及其行为来帮助你快速入门。

¥Whether you are starting with notifications or have existing knowledge, this document aims to give you a quick start by explaining the different notification types and their behavior that you should understand.

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

¥Remember that Expo's notification support builds on top of the native functionality provided by Android and iOS. The same concepts and behaviors from native platforms apply to Expo apps. If you are unsure about a specific notification feature, see each platform's official documentation.

远程和本地通知

¥Remote and Local notifications

  1. 推送通知:(也称为 "远程通知")从远程服务器发送到用户设备的通知。

    ¥Push Notifications: (Also called "remote notifications") Notifications that are sent to a user's device from a remote server.

  2. 本地通知:(也称为 "应用内通知")从应用内部创建和显示的通知。由于创建这些通知的许多 API 都会在特定时间创建它们,因此有时它们也可能被称为 "预定通知"。

    ¥Local Notifications: (Also called "in-app notifications") Notifications that are created and displayed from within the app. Since many of the APIs that create these notifications will create them at a particular time, these may also sometimes be called "scheduled notifications".

expo-notifications 支持推送和本地通知。你必须使用 开发构建 来使用推送通知,因为 Expo Go 不支持它们。

¥expo-notifications supports both push and local notifications. You must use a development build to use push notifications since they are not supported in Expo Go.

本指南的其余部分重点介绍推送通知。

¥The rest of this guide focuses on push notifications.

推送通知传递

¥Push notification delivery

当推送通知到达你的应用时,其行为取决于应用的状态和通知类型。让我们澄清一下术语:

¥When a push notification arrives to your app, its behavior depends on the app's state and the type of notification. Let's clarify the terminology:

应用状态

¥Application states

  • 前台:应用正在前台积极运行。

    ¥Foreground: The app is actively running in the foreground.

  • 后台:应用正在后台运行,"minimized"。

    ¥Background: The app is running in the background, "minimized".

  • 已终止:该应用是 "killed",通常通过应用切换器中的滑动手势来实现。在 Android 上,如果用户从设备设置中强制停止应用,则必须手动重新打开它才能使通知开始工作(这是 Android 的限制)。

    ¥Terminated: The app was "killed", usually by a swipe-away gesture in the app switcher. On Android, if the user force-stops the app from device settings, it must be manually reopened for notifications to start working (this is a limitation of Android).

推送通知行为

¥Push Notification Behaviors

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

¥For any kind of notification, when the app is in the foreground, the app is in control of how an incoming notification is handled. The app may present it directly, show some custom in-app UI, or even ignore it (this is controlled by NotificationHandler). When the app is not in the foreground, the behavior depends on the type of notification.

下表总结了将推送通知发送到设备时发生的情况:

¥The table below summarizes what happens when a push notification is delivered to the device:

通知类型前台应用后台应用应用已终止
通知消息带有数据负载的通知消息交付运行 NotificationReceivedListenerJS 任务操作系统显示通知操作系统显示通知
无头后台通知交付运行 NotificationReceivedListenerJS 任务交付运行 JS 任务交付运行 JS 任务

对于用户与通知交互的情况(例如,通过按下操作按钮),以下处理程序可供你使用。

¥For the cases when user interacts with the notification (for example by pressing an action button), the following handlers are made available to you.

应用状态监听器被触发
前景NotificationReceivedListenerNotificationResponseReceivedListener
背景NotificationResponseReceivedListener
已终止useLastNotificationResponsegetLastNotificationResponseAsync

在上表中,每当 NotificationResponseReceivedListener 被触发时,同样的情况也适用于 useLastNotificationResponse 钩子。

¥In the table above, whenever NotificationResponseReceivedListener is triggered, the same would apply to the useLastNotificationResponse hook.

当应用未运行或被终止并通过点击通知重新启动时,可能会或可能不会触发 NotificationResponseReceivedListener。为了可靠地捕获响应,我们建议使用 useLastNotificationResponsegetLastNotificationResponseAsync。我们计划在未来的版本中改进此行为。

推送通知类型

¥Push notification types

通知消息

¥Notification Message

通知消息是一种指定演示信息(例如标题或正文)的通知。

¥A Notification Message is a notification that specifies presentational information, such as a title or body text.

  • 在 Android 上,这对应于包含 AndroidNotification 的推送通知请求

    ¥On Android, this corresponds to a push notification request that contains AndroidNotification

  • 在 iOS 上,这对应于包含 aps.alert dictionary 和设置为 alertapns-push-type 标头的推送通知请求。

    ¥On iOS, this corresponds to a push notification request that contains aps.alert dictionary and the apns-push-type header set to alert.

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

¥When you use the Expo Push Service, and specify title, subtitle, body, icon, or channelId, the resulting push notification request is a Notification Message.

通知消息的典型用例是立即将其渲染给用户,而无需进行任何额外处理。

¥The typical use case for a Notification Message is to have it presented to the user immediately without any extra processing being done.

带有数据负载的通知消息

¥Notification Message with data payload

这是一个仅适用于 Android 的术语 (查看官方文档),其中推送通知请求包含 data 字段和 notification 字段。

¥This is an Android-only term (see the official docs) where a push notification request contains both data field and a notification field.

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

¥On iOS, extra data may be part of a regular Notification Message request. Apple doesn't distinguish between Notification Message which does and does not carry data.

无头后台通知

¥Headless Background Notifications

无头通知是一种远程通知,它不直接指定标题或正文等展示信息。除了以下* 例外,无头通知不会渲染给用户。相反,它们携带数据(JSON),这些数据由通过 registerTaskAsync 在你的应用中定义的 JavaScript 任务处理。任务可以执行任意逻辑。例如,写入 AsyncStorage,发出 api 请求,或显示其内容取自推送通知数据的本地通知。

¥Headless Notification is a remote notification that doesn't directly specify presentational information such as the title or body text. With the exception below*, headless notifications are not presented to users. Instead, they carry data (JSON) which is processed by a JavaScript task defined in your app via registerTaskAsync. The task may perform arbitrary logic. For example, write to AsyncStorage, make an api request, or present a local notification whose content is taken from the push notification's data.

我们使用术语 "无头后台通知" 来指代 Android 上的 数据消息 和 iOS 上的 后台通知。它们的主要相似之处在于这两种通知类型都允许仅发送 JSON 数据,并由应用进行后台处理。

无头后台通知能够运行自定义 JavaScript 来响应通知,即使应用已终止。这很强大,但有一个限制:即使通知已传送到设备,操作系统也不能保证将其传送到你的应用。这可能由于多种原因而发生,例如在 Android 上启用 休眠模式 时,或者当你发送太多后台通知时 - Apple 建议不要启用 发送超过两三个小时

¥Headless Background Notifications have the ability to run custom JavaScript in response to a notification even when the app is terminated. This is powerful but comes with a limitation: even when the notification is delivered to the device, the OS does not guarantee its delivery to your app. This may happen due to a variety of reasons, such as when Doze mode is enabled on Android, or when you send too many background notifications — Apple recommends not to send more than two or three per hour.

当你使用 Expo 推送服务并仅指定 data_contentAvailable: true(以及其他非交互式字段,如 ttl)时,生成的推送通知请求会产生无头背景通知。

¥When you use the Expo Push Service, and specify only data and _contentAvailable: true (and other non-interactive fields such as ttl), the resulting push notification request produces a Headless Background Notification.

要在 iOS 上使用无头后台通知,你必须先对其进行 configure 操作。

¥To use Headless Background Notifications on iOS, you have to configure them first.

经验法则是,如果你不需要在后台运行 JavaScript,则最好使用常规通知消息。

¥The rule of thumb is to prefer a regular Notification Message if you don't require running JavaScript in the background.

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

¥* The exception is when you specify title or message inside of data. In that case, expo-notifications package automatically presents the headless notification on Android, but not on iOS. We're planning to make this behavior more consistent across platforms in a future release.

仅数据通知

¥Data-only Notifications

Android 有 数据消息 的概念。iOS 没有完全相同的概念,但一个接近的概念是我们所说的 无头后台通知

¥Android has a concept of Data Messages. iOS does not have exactly the same concept, but a close equivalent is what we call Headless Background Notifications.

你可能还会遇到术语 "静默通知",这是不向用户显示任何内容的通知的另一个名称 - 我们将其描述为 无头后台通知

¥You may also come across the term "silent notification", which is yet another name for notifications that don't present anything to the user — we describe these as Headless Background Notifications.

外部参考

¥External references

这是 Android 和 iOS 上推送通知的官方资源的非详尽列表:

¥This is a non-exhaustive list of official resources for push notifications on Android and iOS: