Check out what’s new from Firebase at Google I/O 2022. Learn more

FCM 注册令牌管理的最佳实践

如果您使用 FCM API 以编程方式构建发送请求,您可能会发现,随着时间的推移,您会通过向具有陈旧注册令牌的非活动设备发送消息来浪费资源。这种情况可能会影响 Firebase 控制台中报告的消息传递数据或导出到 BigQuery 的数据,表现为传递率急剧下降(但实际上并非有效)。本指南讨论了您可以采取的一些措施,以帮助确保有效的邮件定位和有效的传递报告。

基本最佳实践

在任何使用 FCM API 以编程方式构建发送请求的应用程序中,您都应该遵循一些基本实践。主要的最佳实践是:

  • 在您的服务器上存储注册令牌。服务器的一个重要角色是跟踪每个客户端的令牌并保持更新的活动令牌列表。我们强烈建议在您的代码和服务器中实现令牌时间戳,并定期更新此时间戳。
  • 删除已存储的过时令牌。除了在明显的无效令牌响应情况下删除令牌外,您可能还需要监视令牌已过时的其他迹象。本指南讨论了实现此目标的一些选项。

检索和存储注册令牌

在您的应用程序首次启动时,FCM SDK 会为客户端应用程序实例生成一个注册令牌。这是您必须包含在来自 API 的目标发送请求中的令牌,或添加到目标主题的主题订阅中。

正如我们的客户端设置指南中所述,您的应用应在初始启动时检索此令牌,并将其与时间戳一起保存到您的应用服务器。此时间戳必须由您的代码和服务器实现,因为 FCM SDK 不为您提供。

此外,将令牌保存到服务器并在其更改时更新时间戳也很重要,例如:

  • 该应用程序已在新设备上恢复
  • 用户卸载/重新安装应用程序
  • 用户清除应用数据。

检测来自 FCM 后端的无效令牌响应

确保检测到来自 FCM 的无效令牌响应,并通过从系统中删除任何已知无效的注册令牌来响应。使用 HTTP v1 API,这些错误消息可能表明您的发送请求针对的是陈旧或无效的令牌:

  • UNREGISTERED (HTTP 404)
  • INVALID_ARGUMENT (HTTP 400)

有关详细信息,请参阅错误代码

如果您收到针对目标令牌的这些响应中的任何一个,则可以安全地删除您对该令牌的记录,因为它将永远不再有效。但是,请记住,仍然存在令牌实际上无效但没有任何迹象的情况。例如,有时 FCM 后端无法验证设备是否已永久离线。

确保注册令牌的新鲜度

确定令牌是新鲜的还是陈旧的并不总是那么简单。为了涵盖所有情况,您应该在考虑令牌陈旧时采用阈值;我们的建议是两个月。任何超过两个月的代币都可能是非活动设备;否则,活动设备将刷新其令牌。

定期更新代币

我们建议您定期检索和更新服务器上的所有注册令牌。这要求您:

  • 在您的客户端应用程序中添加应用程序逻辑以使用适当的 API 调用检索当前令牌(例如token(completion):用于 Apple 平台或getToken()用于 Android),然后将当前令牌发送到您的应用服务器进行存储(带有时间戳)。这可能是配置为涵盖所有客户端/令牌的月度作业。
  • 添加服务器逻辑以定期更新令牌的时间戳,无论令牌是否已更改。

无论您遵循什么时序模式,请确保定期更新令牌。每月一次的更新频率可能会在电池影响与检测非活动注册令牌之间取得良好平衡。通过执行此刷新,您还可以确保任何处于非活动状态的设备在再次变为活动状态时都会刷新其注册。比每周更频繁地进行刷新没有任何好处。

从主题中取消订阅过时的令牌

管理主题订阅以删除过时的注册令牌是另一个考虑因素。它包括两个步骤:

  1. 您的应用应每月和/或每当注册令牌更改时重新订阅主题。这形成了一个自我修复的解决方案,当应用再次激活时,订阅会自动重新出现。
  2. 如果应用实例闲置了 2 个月(或您自己的过时窗口),您应该使用Firebase Admin SDK取消订阅主题,以从 FCM 后端删除令牌/主题映射。

这两个步骤的好处是您的扇出将发生得更快,因为有更少的陈旧令牌可供扇出,并且您的陈旧应用程序实例将在它们再次处于活动状态时自动重新订阅。

衡量交付成功

通常,我们建议根据从活跃使用的应用实例中观察或捕获的操作来定位消息。如果您定期向拥有大量订阅者的主题发送消息,这一点尤其重要;如果这些订阅者中有一部分实际上是不活跃的,那么随着时间的推移,对您的交付统计数据的影响可能会很大。

在将消息定位到令牌之前,请考虑:

  • Google Analytics、BigQuery 中捕获的数据或其他跟踪信号是否表明令牌处于活动状态?
  • 之前的交付尝试是否在一段时间内一直失败?
  • 在过去两个月内,您的服务器上的注册令牌是否已更新?
  • 对于 Android 设备, FCM 数据 API是否报告了由于droppedDeviceInactive导致的高比例消息传递失败?

有关传递的更多信息,请参阅了解消息传递