如何管理 FCM 推送令牌

Posted

技术标签:

【中文标题】如何管理 FCM 推送令牌【英文标题】:How to manage FCM push tokens 【发布时间】:2021-05-17 01:29:23 【问题描述】:

我想找到一种可持续的解决方案来存储用于推送通知的 FCM 令牌。我正在将 React Native 与 Firebase 一起使用。

要求是:

    基于用户的应用程序 支持每位用户多台设备 任何时候都没有存储过时的令牌。

我目前的做法是:

维护一个带有列的表user_devices

user_id, device_uuid fcm_token

保持对 fcm_token 和 device_uuid 的唯一性约束。

关键事件,包括但不限于:

应用程序启动 登录 onTokenRefresh

将以下内容发送到后端:

device unique id FCM 注册令牌 用户 ID,如果有(通过身份验证令牌完成)

然后后端使用上述值更新一行。如果设备 uuid 存在,这意味着我们会覆盖该设备 uuid 的令牌(可能还有 user_id)。

上述方法存在缺陷,因为:

device unique id 可以随时更改(设备重置、更新、应用重新安装等...) 注册令牌可以随时更改

换句话说,表最终存储了许多过时的令牌,应用程序后端向这些过时的令牌发送通知。

此外,“设备”前端页面(向用户显示他们的注册设备并从上表中读取)显示了许多重复的设备,这些设备实际上代表相同的设备但具有不同的设备 uuid。

一个缓解步骤可以是定期向存储在带有dry_run=true 的表中的所有令牌发送通知。然后,删除带有发生错误的标记的行。这很糟糕,因为这意味着在一段时间内,表中的令牌是陈旧的。

我已经在线扫描了多个资源,包括 FCM 文档,但没有提及在实际应用程序中存储和维护这些令牌。有什么建议的方法吗?

【问题讨论】:

【参考方案1】:

惯用方法是在发送消息的 Firebase 云消息传递 API 告诉您它无效时删除令牌。

有关如何执行此操作的示例,您可以查看 sending notifications 的 Cloud Functions 示例,它执行以下操作:

  const response = await admin.messaging().sendToDevice(tokens, payload);
  // For each message check if there was an error.
  const tokensToRemove = [];
  response.results.forEach((result, index) => 
    const error = result.error;
    if (error) 
      functions.logger.error(
        'Failure sending notification to',
        tokens[index],
        error
      );
      // Cleanup the tokens who are not registered anymore.
      if (error.code === 'messaging/invalid-registration-token' ||
          error.code === 'messaging/registration-token-not-registered') 
        tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
      
    
  );
  return Promise.all(tokensToRemove);

因此,每次您通过 FCM 发送多条消息时,都会从数据库中剔除无效/过时的令牌。

【讨论】:

谢谢。这似乎是上述不完美解决方案的被动变体(定期检查存储令牌的有效性)。这意味着该表可以存储大量陈旧的令牌,我们会执行不需要的广播调用。 有一些应用程序,例如 PagerDuty,可以实现这一点——它们提供了一个面向用户的页面,其中列出了用户的设备,并且不会出现重复项。我想知道他们使用什么样的技术?此外,与返回错误消息匹配的字符串似乎非常不可持续。真是让我吃惊,这是惯用的方法。 代码在令牌使用一次后立即删除。在 FCM API 中,这是我所知道的最好的。我找到了更好的方法,请作为自我回答分享。 我想不出任何不涉及 FCM 方面更改的解决方案,因此问题:)。我相信一个潜在的解决方案是让onRefreshToken 传入之前的注册令牌(或之前的令牌链),但我的猜测是这会破坏这些令牌首先轮换的一些原因。通过削减上述三个要求之一,大多数实际应用程序很可能不会面临这个问题。其他生产级应用程序可能使用一组启发式方法。

以上是关于如何管理 FCM 推送令牌的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 推送通知 - 如何跟踪用户 FCM 令牌?

如何使用 phonegap 推送插件监控 FCM 令牌刷新

如何检测真正的 iOS/APNS 推送令牌何时向 Firebase Cloud Messaging (FCM) 注册?

通过 FCM 发送推送通知时何时使用 iOS 设备令牌?

无法获取设备的推送令牌。检查您的 FCM 配置是不是有效

FCM - 通过设备令牌和环境/组发送 android 推送通知