处理FCM设备组的刷新令牌

Par*_*hit 7 android node.js firebase firebase-cloud-messaging

我正在尝试通过Node.js服务器在我的Android应用程序中实现Firebase云消息传递,并且我已经陷入了一个用例.

我看到了使用注册令牌创建设备组的Firebase教程,以便在登录相同用户的情况下向所有设备发送消息/通知,我不明白当其中一个注册令牌被onTokenRefresh()方法刷新时会发生什么.

如何区分要更改的令牌,因为所有令牌都属于同一个用户?

更新:

好的,所以现在我又陷入了另一个阻塞用例.我正在创建一个由我的服务器中的用户ID标识的用户组.如果用户立即卸载并重新安装应用程序而另一个用户登录设备,如果我在之前的用户组上调用gcm消息,则此设备仍会收到该消息.

gcm是否有任何方法可以识别发送通知的设备是否已登录,如果是,是否使用与该组相同的用户登录?

Jef*_*ett 7

还有另一种使用 Cloud Firebase 函数解决此问题的方法。

由于所有令牌都属于同一用户,我将如何区分要更改的令牌?

使用 Firebase 函数,您不必这样做。在 onTokenRefresh() 中,您将新令牌发送到服务器。

例如:

用户有 3 台设备,每台设备都有一个已发送到服务器的令牌。

*** deviceTokenA/B/C 代表令牌的 UID ......我们不知道它们是什么,也不知道它们属于哪个设备。

UserId:
    Device Tokens:
        deviceTokenA: true,
        deviceTokenB: true,
        deviceTokenC: true,
Run Code Online (Sandbox Code Playgroud)

现在,用户在触发 deviceTokenA 的设备上。刷新令牌,并调用 onTokenRefresh(),将令牌发送到该集合。

onTokenRefresh() {
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    sendTokenToServer(refreshedToken);
}

sendTokenToServer(String refreshedToken) {
    // send to Firebase or Firestore Database, put in the Device_Tokens collection.  }
Run Code Online (Sandbox Code Playgroud)

现在,您将在集合中拥有 4 个令牌。

 UserId:
        Device Tokens:
            deviceTokenA: true,  // this one has been "unregistered"
            deviceTokenB: true,
            deviceTokenC: true,
            deviceTokenD: true, // this one has been registered.
Run Code Online (Sandbox Code Playgroud)

deviceTokenA 不再适用,因为它已刷新,不再附加到实际设备。

在查看设备令牌时,我们仍然不知道哪些是好的,哪些是坏的,哪些令牌属于哪个设备。没关系!

所以,然后创建一个 forEach 循环,获取每个 Token,然后向每个 Token 发送一个 FCM,FCM 可以让我们知道哪些 Token 发送成功。其中之一将返回错误。如果它返回一个错误,说令牌坏了,我们就可以捕获错误并删除该令牌,这样就不会再次调用它。

// outside for Each loop
     var promiseHolder = [];


// create a forEach loop, iterating through the collection of deviceTokens
// within that loop, put:

let innerPromise = admin.messaging().send(message)
.then(response => {
    console.log('notification sent success: ' + response);
})
.catch((error) => {
    console.log('Error sending notification: ' + error);

    // if the error == bad token message, then Delete the Token.
    if (error == 'Error: Requested entity was not found.') {
        console.log('you matched the error, token doesn't work, handle here.');

        //delete the old token
        return admin.firestore()doc(`users/${userID}/device_tokens/${token_id}`).delete();
     }
}

// still within forEach loop
promiseHolder.push(innerPromise);

// end the forEach Loop, and outside forEachLoop put:
return Promise.all(promiseHolder);
Run Code Online (Sandbox Code Playgroud)


AL.*_*AL. 5

所以我一直在考虑如何使用这种情况.首先,让我们在调用onRefreshToken()时放入实例:

这不会被频繁调用,需要进行密钥轮换并处理实例ID更改,原因如下:

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

猜猜一下,你可以说'onTokenRefresh()`将在上面发生之后被调用,如果设备在线(当然它必须在线以获得新的令牌).所以我想这就是我如何继续这个场景:

首先,在注册时,我会保存注册令牌并将其与另一个标识符配对,假设我的App Server 中有一个deviceId(因为我们处于具有多个设备的用户的场景中).

因此,假设我添加了3个注册令牌,这些令牌也与他们的deviceIds配对.我将它们全部添加到设备组.

现在说其中一个设备触发了onTokenRefresh(),我会立即向我的App Server发送一个删除请求,用于当前与该deviceId配对的注册令牌(你还应该在它连接到的任何设备组中将其删除),使用新的,然后将其重新添加到相应的设备组.

这是我能想到的最简单的方法.这里的关键是您将注册令牌与另一个标识符配对,并使用它来查找需要替换的注册令牌.

  • @ AL.你能告诉我你用作deviceId的东西吗? (2认同)