使用 FCM 通知您的用户

2,645 阅读8分钟

作者:史婧羽,开发技术推广工程师,Partner DevRel

本文为 Android 电量管理系列连载的第二篇,希望您能在阅读过程中收获设备续航方面的战略洞见和实践指导。

通知是让应用用户保持联系和获取更新的重要渠道。Android 提供通知 API 用于在设备上创建和发布通知,但这些通知经常由外部事件触发,并从应用服务器发送至应用。

本文将解释何时以及如何生成这些远程通知,以便为用户提供及时更新并尽量省电。

用 FCM 实现远程通知

我们推荐使用 Firebase 云消息 (FCM) 发送远程通知到 Android 设备。FCM 是一种免费的跨平台消息传递解决方案,每日可靠传递千亿条消息。尤其是用于发送远程通知,以通知客户端应用数据可同步。如果您仍使用已被弃用的 Google 云消息 (GCM) 或 C2DM 库,是时候升级到 FCM 了!

有两种类型的 FCM 消息可选:

  • 通知消息,简化了通知处理且默认高优先级。
  • 数据消息,适用于在客户端应用内处理 FCM 消息。

您可以把数据信息的优先级设为高或普通。如需进一步了解 FCM 消息和消息处理,可参阅 Firebase 博客上的这篇文章

FCM 针对 Android 电源管理特性进行了优化。运用合适的消息优先级和类型,能帮您及时通知用户,还能帮用户省电。如需进一步了解电源管理,可参阅这篇文章:"Android 9 Pie 中的 Moar 电源及未来"。

是否需要发送通知?

您发送的所有通知都应该设计良好且可执行,并且能为用户提供及时相关的信息。我们推荐您遵循这些通知指导原则,并避免向用户发送垃圾信息。没人想被无关或杂乱无章的通知打扰。如果您的应用这样做,用户可能屏蔽通知甚至卸载您的应用。

Material Design 通知文档中的 ‘何时不使用’ 通知一节列出了不应该向用户发送通知的一些情况。例如,普通优先级 FCM 数据消息的常见用例是告诉应用有新内容准备同步,但这一操作无需用户交互。所以同步不需要通知用户,应在后台静默进行,而您可以用 WorkManager (当 WorkManager 达到稳定版本后,将是最为推荐的后台处理解决方案。) 或 JobScheduler API 来安排同步。

先发布一个通知

如果您需要发送远程通知,则应始终在收到 FCM 消息后尽快发布通知。如果在发布通知前添加任何额外网络请求,都会导致发送给某些用户的通知延迟。如果处理不当,通知可能根本不会被用户看到,参阅下节 "避免后台服务"。

⚠️ 发布通知前应避免添加任何额外网络请求

还要记住,根据设备状态、用户操作和应用行为,一个或多个省电功能可能会限制应用的后台工作。应用的 jobs 和 alarmas 可能被延迟,且访问网络的功能可能被限制。

因此,为确保及时传递通知,应始终在收到 FCM 消息后立即显示通知,然后再进行网络获取或调度任务等其他工作。

善用 FCM 消息有效负载

如果您需要在收到 FCM 消息后发布通知,则应在 FCM 消息有效负载中包含通知所需的全部数据。

这个建议同样也适用于数据同步——我们推荐应用在 FCM 有效负载中发送尽量多的数据,如必要,在应用打开时再加载剩余数据。如果网络良好,数据很可能在用户打开应用前就同步完成,所以用户不会看到加载进度条。如果网络不好,使用 FCM 有效负载中的内容就可以确保发一条通知给用户,从而仍然可以及时通知用户。然后用户可以打开应用再加载全部数据。

您还可以用 Capillary 等库对 FCM 消息进行端到端加密。下图显示了 FCM 消息的一般处理流程。

需要更多数据?

虽然 FCM 消息有效负载很方便,但有最大 4KB 限制。如果您需要发送带图片等丰富媒体内容的通知,或想通过向应用持续同步媒体内容来改善用户体验,就需要超过 4KB 有效负载限制。对此,我们推荐将 FCM 消息与 WorkManager 或 JobScheduler API 配合使用。

如果您需要发布有丰富媒体内容的通知,我们推荐您先用 FCM 消息中的部分内容发布通知。然后调度一项任务获取其余内容。任务完成后再更新通知 (如果此时通知仍处于活跃状态)。例如,可以在 FCM 有效负载中包含内容缩略图或预览并先在通知中发布。然后调度一项任务获取媒体文件。注意,如果从 FCM 的 handler 中进行任务调度,则有可能当用户启动应用时,所调度的任务还没完成。这种情况应妥善处理。

简言之,用 FCM 消息有效负载中的数据发布通知,并保持首先更新应用内容。如果需要更多数据,则用 WorkManager 或 JobScheduler API 调度任务。

避免后台服务

常见错误是在 FCM 的 handler 中使用后台服务,因为根据 Google Play 政策近期变更 (自 2018 年末起,Google Play 将要求最低目标 API Level),系统会停止后台服务

Android 9 Pie 也会在开启省电模式时强制限制后台执行。当使用普通优先级的 FCM 消息时,启动后台服务会导致 IllegalStateException。高优先级消息会授权您短暂白名单窗口,允许启动后台服务。但使用这个窗口来启动后台服务从而进行网络连接,服务可能被系统终止,因为这个白名单窗口是为用于发布通知而设计的。

总而言之,应避免使用后台服务,而是用 WorkManager 或 JobScheduler API 来执行后台操作。

电源和消息优先级

Android 6 Marshmallow 引入了 Doze 模式。FCM 针对 Doze 进行了优化,您可使用高优先级 FCM 消息立即通知用户。在 Doze 模式,普通优先级消息被延迟至维护窗口。这一功能让系统能在设备空闲时省电,但同时确保用户收到时效性强的通知。例如:即时通讯应用需要向用户发送好友消息或来电,而家庭监护应用需要向用户发送警报通知。在这些场景中,可以使用高优先级 FCM 消息。

此外,Android 9 Pie 还引入了应用待机分组应用限制的新功能。

下表显示了不同电源管理功能对 FCM 消息传递行为的影响。

Doze: developer.android.google.cn/training/mo…

Doze "on the go": developer.android.google.cn/about/versi…

应用待机分组: developer.android.google.cn/about/versi…

应用限制: developer.android.google.cn/topic/perfo…

省电模式: developer.android.google.cn/about/versi…

可能受限: developer.android.google.cn/topic/perfo…

★ 注意: 自 2019 年 1 月起,应用限制 (在电池设置里) 将包括对 FCM 消息的限制。可通过 isBackgroundRestricted API 检查应用是否处于受限状态。如果应用处于受限状态,FCM 消息则根本不会被传递至应用。这对高优先级和普通优先级 FCM 消息均适用,且无论应用处于前台还是后台。

应用待机分组根据应用所在的分组实施不同程度的限制。根据应用所属分组,每日发送的高优先级消息数量可能受限。当您发送达到所在分组的最高数量后,所有后续高优先级消息都会被降级为普通优先级。详见电源管理限制

高优先级 FCM 消息的设计初衷是发送会触发用户交互的远程通知。如果您只将高优先级消息用于这些目的,您的高优先级将被立即传递且远程通知会被无延迟显示。此外,当高优先级消息通知让用户打开应用时,应用会被提升至活跃分组,不再受应用待机分组对 FCM 高优先级数量限制。下面的例子显示,用户点了一条高优先级 FCM 消息触发的通知后,即时通讯应用被移至活跃分组。

但如果您使用高优先级消息发送通知给被已被用户屏蔽的通知渠道或触发无需用户交互的后台任务,就可能浪费应用分组的高优先级消息份额。达到数量上限后,将再也无法发送紧急通知。

总之,应仅在传递时效性强的通知给用户时,才使用高优先级 FCM 消息。这样可以确保这些消息和后续的高优先级消息能够及时送达用户且不被降级。而如果是需要触发无需立即执行的事件,如:时效性不强的通知或后台数据同步,则应使用普通优先级消息。

用 Android 9 测试!

我们强烈推荐您在上述全部电源管理功能环境下测试您的应用。如需进一步了解处理代码中 Android 的 FCM 消息,请访问 Firebase 博客

感谢您帮助促进 Android 生态系统,打造更好的应用程序,并为用户省电!

点击这里前往 Firebase 官方文档 查看更多信息

更强续航,尽在 Android 9 Pie!