Firebase云消息传递设备组泄漏

4
我将开发一个使用设备组功能的应用程序。据我所知,我需要首先通过Android客户端中的onTokenRefresh方法向服务器发送当前的注册令牌,然后通过HTTP请求将这个注册令牌添加到正确的设备组中(如果不存在则创建)。然而,我认为存在潜在的泄漏注册令牌的风险,因为Android应用程序用户可能会多次清除应用程序数据。如何防止这种情况?当达到20个成员的限制时会发生什么?还有可能检查某个组是否已经存在吗?

1
跨贴:https://groups.google.com/d/msg/firebase-talk/B8wG6CMC8lA/X6KvwaydAwAJ - Frank van Puffelen
4个月后,您有任何进展吗?我想知道在设备组中如何处理过期的令牌;您应该以某种方式唯一地标识设备... - Galya
1
@Galya 我决定不使用设备组,而是直接使用包含用户ID的主题。 - Matis
根据这篇文章,按用户ID创建主题并不是一个好主意。 - ElectroBuddha
2个回答

2
我发现可能会泄漏注册令牌,例如Android应用程序用户可能多次清除应用程序数据。如何防止这种情况发生?
如果通过“防止”您的意思是在应用程序管理器中禁用您的应用程序的“清除数据”,则应参考此帖子。接受的答案指出这是不可能的。
然而,Jakar的答案提供了一个解决方法,即不是使用“清除数据”,而是使用“管理空间”。尚未尝试过,所以我不能确定。但是,赞成票已经说明问题。
但是,如果用户清除了应用程序的数据,您应该参考FirebaseInstanceId文档中所述的内容:
实例ID是稳定的,除非:
应用程序删除实例ID
应用程序恢复到新设备上
用户卸载/重新安装应用程序
用户清除应用程序数据
在以上情况下,将生成一个新的实例ID,并且应用程序需要重新创建先前生成的授权令牌,实现onTokenRefresh()。
当超过20个成员的限制时会发生什么?
不确定问题是什么。但是,如果你指的是将设备添加到设备组中超过最大值...
在FCM:设备组消息传递文档中没有明确说明,但是如果您参考“添加到组”部分,则会说明:
成功的操作返回一个notification_key。
因此,我认为如果您尝试将另一个设备添加到已经达到最大值的设备组中,该操作将失败。
如果您认为要超过20个,请改用主题。但是我不知道您的用例是什么,所以由您决定。
是否可以检查某个组是否已存在?
是的,您可以使用FirebaseInstanceId.getInstance().getInstanceId()方法来检查实例ID是否存在。如果实例ID不存在,则可以创建新的实例ID。
为此,您应该利用notification_keynotification_key_name。根据文档

notification_key_name是给定组独有的名称或标识符(例如,可以是用户名)。notification_key_namenotification_key是一组注册令牌独有的。如果您对于相同的发送者ID有多个客户端应用程序,则notification_key_name每个客户端应用程序都必须唯一。这确保了消息仅发送到预期的目标应用程序。

并强调以下声明:

设备组的基本管理——创建和删除组以及添加或删除设备——通常通过应用服务器执行。

密钥和名称应该在您的服务器上,这样您就可以检查它是否已经存在。

2
“Preventing” 的意思是防止注册 ID 泄漏。清除应用程序数据只是一个快速泄漏的示例 - 如果分配了新令牌并且旧令牌未被删除,则会发生泄漏。 - Matis
我明白了。-- 如果一个新的令牌被分配,并且旧的令牌没有被移除,则会出现泄漏 -- 这些不是在您的服务器端简单处理吗?利用标准ID?其他情况应该在客户端应用程序本身处理吗? - AL.
3
规范化ID可能是一种解决方案,但在FCM文档中并没有明确提到(只有在GCM中有提到)。(https://firebase.google.com/docs/cloud-messaging/server#response中提到了一下,但没有解释为什么或何时返回这些规范化ID)。但我想使用设备组,因此仅在将设备添加到组时才对其进行操作。我还想澄清我的最后一个问题:我知道我需要在应用程序服务器上存储组,但有时它们可能会与FCM服务器失去同步,这就是为什么我想检查是否存在具有给定“notification_key_name”的组。 - Matis
我也很想知道规范ID在设备组消息中如何使用。或者在设备组的情况下,FCM服务器是否会自动使用规范ID? - Sreekanth

2

我目前正在尝试以下操作,已有一定的成功,但尚未完全测试或扩展。

应用程序使用Firebase作为后端,并添加了FCM以实现推送通知。

我需要分组来处理当用户可能在不同设备或多个设备上时的情况。

我将返回的notification_key值和每个设备的registration_id(令牌)与个人资料存储。

profiles
   -profile_id
     -FCM
       -notification_key:value
       -registration_ids
         -device_1_uuid:token_for_device_1
         -device_2_uuid:token_for_device_2

当用户首次登录时,FCM节点下没有数据,即没有通知键和注册ID。
每次用户登录时,它们都会连接到其profile_id。
我获取FCM令牌,然后:
如果没有通知键(即第一次在任何设备上使用),我将使用profile_id作为notification_key_name创建组并存储返回的通知键。
如果有通知键(返回登录或在新设备上的第一次登录),我查看当前设备是否有注册ID,如果没有(在新设备上的第一次登录),则将device_uuid:token对添加到registration_ids中。
如果有(返回登录),我从FCM组中删除存储的令牌,并使用刚刚获得的令牌替换我的存储registration_ids中的旧令牌。
现在,我可以通过向他们的profile_id发送消息来向该用户(profile)使用的所有设备发送消息,并且我不应该泄漏令牌,因为我会删除旧令牌。
然而,由于似乎没有API可以仅读取组和令牌,因此我无法知道。这样,可以偶尔清理组。
此外,我的早期代码出现了错误,我没有捕获通知键,因此现在我无法添加,删除或执行任何操作以处理我的某个组。我讨厌这个想法,因为我必须永远留下在Firebase云中烧毁的组。
我认为FCM应该提供更多API访问权限,以帮助我们保持整洁。

我正在遵循几乎相同的方法,但我有一个问题。如果没有任何设备与其关联,FCM会自动删除设备组。你如何处理这种情况?据我所知,如果令牌不再有效,则在FCM中自动从组中删除它。 - Naveed Ahmed
当我从组中删除一个令牌,因为它已经在我的设备上被替换掉了,如果它是最后/唯一的令牌,则 FCM 组将被删除,并且当我尝试注册新令牌时会出现错误。我通过其文本消息捕获错误,即“未找到通知键”,并在其上调用我的 create_group 函数,以便使用相同的通知键重新创建一个新组并将令牌添加到其中。这感觉有点 hacky,但类似地,我还使用错误文本“通知键已存在”作为条件来为新设备注册其他令牌。 - blythburgh
是的,这就是我现在处理它的方式,但我想知道是否有更好的方法,因为这种感觉有点不正规。 - Naveed Ahmed
很高兴发现我不是孤单的......捕获错误是我的方法,用来确定我是否需要在某些情况下添加一个令牌到一个组或创建一个组。但我也认为这是一种巧妙的方式。 - Phillip Stack
是的,我使用硬件uuid。我使用ngCordova插件$cordovaDevice来获取它。它有一个.getUUID()方法。这对我在iOS上有效。我尚未测试Android。设备准备就绪后,我将uuid捕获到rootScope中,并在应用程序的许多位置检查它以实现不同的目的,其中推送通知只是其中之一。 - blythburgh
显示剩余2条评论

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