Firebase的应用程序令牌在哪个时期更改,如何管理?

62

我刚接触Firebase,像一个学步的婴儿一样学习。目前为止,我已经成功使用由Firebase框架为我的手机生成的令牌将消息发送到了我的手机。现在问题来了(我觉得有些棘手)。在扩展服务FirebaseInstanceIdService中,有一个名为onTokenRefresh()的方法。由于它被称为“refresh”,那么我认为它会发生变化。我想知道令牌何时被创建以及何时会更改?

如果它更改了,假设我将消息发送到一个当前离线的名为'A'的设备上,那么它将被排队。现在当该设备联网时,它将“刷新”令牌至'B'。由于消息应该交付给令牌'A',所以消息将永远无法传递。我该如何处理这种情况?

3个回答

72

在应用程序首次启动并手机能够连接到Google服务器后,令牌将被生成。由于需要连接性,这可能不会立即发生,但在大多数情况下,用户打开应用程序后几秒钟内就会生成令牌。

一旦生成令牌,将调用方法onTokenRefresh()

正如您指出的,令牌可能会发生变化,此时将再次调用onTokenRefresh()方法。
刷新事件相对较少,不要期望经常看到它。

当刷新令牌发生时,所有已向旧令牌“成功”发送的消息(API返回了消息ID)将被传送。

最后,即使刷新完成后,旧令牌仍将工作一段时间,以允许应用程序将新令牌与其后端进行通信。


13
当用户注册应用程序时,我希望将 FCM token 存储在 Android 应用程序用户表中。当我要向特定用户发送通知时,我将从相应行中获取令牌并发送推送通知。但是,当应用程序用户注销并从同一设备注册新帐户时,数据库上会出现两个行和两个令牌,我感到困惑。如何处理这种情况?设备上的旧令牌会发生什么?请问是否有人能够帮助我? - Roshan Sharma
2
@DiegoGiorgini,您能否在 FCM 文档中添加这些细节吗? - Louis CAD
2
有人能告诉我令牌何时会刷新的原因吗?是否有默认时间,超过该时间令牌一定会刷新? - user734028
2
@RoshanSharma 在将Firebase令牌发送到服务器时,应该附带设备ID。在将新令牌添加到行之前,先查找设备ID是否存在,如果存在则删除,然后再插入令牌。 - Samar Haider
1
@RoshanSharma 你可以在你的应用中调用 FirebaseInstanceId.deleteInstanceId(),然后重置实例 ID,撤销所有令牌并生成新的令牌。 - sandeepmaaram
显示剩余2条评论

31

在您的应用程序初始启动时,FCM的SDK会为客户端应用程序实例生成注册令牌。正如上面所说,这是一个罕见事件。具体而言,当以下情况发生时,注册令牌可能会更改:

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

实例ID为您的应用程序的每个实例提供唯一的ID。实例ID提供一个简单的API来生成安全令牌,授权第三方访问您的应用程序的服务器端管理资源。实例ID服务器甚至可以告诉您安装了您的应用程序的设备上次使用的时间。我们可以使用此信息来决定是保留应用程序中的数据还是发送推送消息以重新与用户互动。

每次设备令牌更改时,它都会在 onTokenRefresh() 方法中反映出来。要在设备令牌更改时获取设备令牌,我们可以调用此方法获取更新后的令牌。

要随时获取设备令牌,我们可以使用 FirebaseInstanceId.getInstance().getToken()方法获取当前设备令牌。获取设备令牌需要一些时间。

单击此处了解更多关于访问设备注册令牌的信息。


请问您能解释一下“应用程序删除实例ID”是什么意思吗? - iDecode

4
  • onTokenRefresh()FirebaseInstanceIdService 已被废弃。
  • 这个调用也已经过时了 FirebaseInstanceId.getInstance().getToken()

相反地,您应该在FirebaseMessagingService中重写onNewToken(String token)。当令牌更改时,此方法将被触发。一旦您重写了此方法,就可以安全地删除包含onTokenRefresh()的FirebaseInstanceIdService。

令牌何时会改变?

  • 应用程序删除实例ID
  • 应用程序在新设备上恢复
  • 用户卸载/重新安装应用程序
  • 用户清除应用程序数据

如何检索当前令牌:

通过调用FirebaseInstanceId.getInstance().getInstanceId():

FirebaseInstanceId.getInstance().getInstanceId()
    .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
        @Override
        public void onComplete(@NonNull Task<InstanceIdResult> task) {
            if (!task.isSuccessful()) {
                Log.w(TAG, "getInstanceId failed", task.getException());
                return;
            }

            // Get new Instance ID token
            String token = task.getResult().getToken();

            // Log and toast
            String msg = getString(R.string.msg_token_fmt, token);
            Log.d(TAG, msg);
            Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

更多信息请访问:https://firebase.google.com/docs/cloud-messaging/android/client 如需管理特定发送者 ID(而非默认发送者 ID)的令牌,请查看此处

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接