刷新设备组的唯一成员用户的令牌时出现意外的行为 [英] Unexpected behavior when refreshing token of a user who is the unique member of a device group

查看:217
本文介绍了刷新设备组的唯一成员用户的令牌时出现意外的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了设备,注册ID和组之间的映射,如这里基本上想出了一个表格,用来存储设备注册ID和它所注册的组的通知密钥(if任何),并添加到我的用户表两个领域,以跟踪用户已登录设备的数量,以及他预先确定的组名称。

不幸的是,在测试的时候,我刷新了一个用户的标记,同时也是设备组的唯一成员。我发现这个行为很奇怪。



我问的问题 here


如果pre vious令牌是设备组中唯一的成员,在刷新之后,它是无效的,但组保持存在,并以某种方式将新的令牌添加到它。我甚至可以成功地从组中删除新的令牌,从而删除它,或者我可以通知组唤醒,并使其自动删除自己



$
$ b


  1. 得到一个新的标记说:
    $ b


    1. reg_id1

    2. 注册 reg_id1 到设备组 test_group (创建它)

    创建组的代码:

      curl --headerAuthorization:your_key
    --header Content-Type:application / json
    -Hproject_id:your_idhttps ://android.googleapis.com/gcm/notification
    -d{\operation \:\create \,\notification_key_name \:
    \ test_group \,\registration_ids\:[\reg_id1\]}




    1. 测试该组是否存在



    $ $ $ $ codeurl -v -HContent-Type:application / json-HAuthorization:key = your_key
    - Hproject_id:your_id
    https://android.googleapis.com/gcm/notification?notification_key_name=test_group


    $你喜欢的方式(删除应用程序数据,如果在Android上或请求新的标记,如果$ b $ ol的在线应用程序)


  2. 使用点3处的命令检查组发生了什么

该组仍然存在(即使现在唯一的标记无效)


  1. 尝试删除旧标记。会发生什么?好的,答案是合理的..我们试图删除的令牌无效了

删除代码

  curl --headerAuthorization:key = your_key
--header Content-Type:application / json-Hproject_id :your_id
https://android.googleapis.com/gcm/notification
-d{\operation \:\remove \,\notification_key_name \ :
\\test_group \,\notification_key \:\group_key \,
\registration_ids \:[\reg_id1 \ ]




  1. 从同一组中删除新的刷新标记!你会得到一个通知键,这意味着没有错误..但等待!怎么可能呢?

  2. 用第三个点的命令再次ping组,并且..这个组仍然存在?! (以前,在原问题出现的时候,在从android中删除新的token的时候,这个组会在这个点之后停止存在。现在curl继续存活)

  3. 尝试通知组然后!

code

< pre $ curl -X POST -Hyour_key
-HContent-Type:application / json
-d'{
notification :{
标题:葡萄牙对丹麦,
body:5比1,
icon:firebase-logo.png,
click_action:http:// localhost:8081
},
to:group_key
}'https://fcm.googleapis.com/fcm/发送




  1. 现在发生的是1失败(这是可以的),如果你尝试重新ping组,它将会奇迹般地消失..

对不起很长,但我想写所有的步骤,以便您可以轻松地重现行为。

有人可以探讨在这一切?
在我的android应用程序,如果用户删除应用程序数据,他将需要再次登录,因为创建/添加到设备组是在登录时,我需要从组中删除旧的令牌(和删除组这是最后一次),以便他能够再次重新进入该组(或创建它)。
但是我不能直接删除旧的标记,因为它是无效的。
仍然存在,即使其唯一成员无效,该组仍然存在。我应该只是通知它唤醒并使其自行删除?
我应该从组中删除新的令牌吗? (在Android中,这将奇怪地导致删除组)

编辑:
测试今天早上我有一个新的用例:


  1. 创建包含reg_id1订阅的组

  2. 刷新reg_id1

  3. 重新创建组说,该组存在(我可以ping它的广告收到通知密钥作出回应)

  4. 尝试从组中删除新的令牌给出错误500

  5. 通知测试小组给出<0>成功和0失败

  6. 尝试从组中删除旧的令牌给回通知键(应该是一个肯定的答案)

  7. 现在群组已经不存在了

EDIT2:

经过大量的测试后,我得出了这些结论:


  • 在android应用程序上刷新一个标记会使其失效,如果它是设备组中的唯一成员,通知该组的简单通知会将其唤醒并使其自动删除。
  • 刷新Web应用程序上的令牌不会使令牌无效,如果它是设备组的唯一成员,则通知组将导致0成功0失败。虽然不可见,但令牌仍然被注册到组中,并且只有当旧的令牌将被移除时组才会消失。在这种情况下,即使在那里旧的令牌也不会同意20台设备的限制(我成功注册并刷新了25个令牌到同一组)。
    现在需要的是在Web应用程序场景中检索旧的令牌以将其从组中删除的方法。这是至关重要的,因为Web应用程序没有唯一的ID因此它不能像Android(与Android ID)映射到注册令牌,旧的令牌甚至不会在通知时显示为失败,这意味着在刷新后几乎不可能检索它。
  • 结束了做。这绝不是优雅的,我必须在我需要和实际发生的事情之间妥协。

    首先,我确认:


    1. 在android中,当一个令牌被刷新时,它会被无效化,因此会自动从它所属的每个组中删除(不是瞬间的,更像是第一次通知或在组上添加/删除的操作)。
      这就是为什么一个简单的通知(而不是dry_run)可以作为唤醒给组,这意味着如果它是最后一个成员,那么这个组将立即死亡。
      请注意,即使令牌失效,如果它是组的最后一个成员,组仍然存在!一个通知会唤醒并杀死它,否则添加更多的设备仍然可以工作!

    2. 在一个web应用程序,而不是更复杂的行为,因为它是依赖于浏览器(惊喜?)。例如在Firefox中刷新的令牌奇迹般地消失,但不会失效。这意味着如果它是一个组中的唯一成员,那么发送一个通知给这个组将会导致0成功和0失败,只有从组中删除旧的令牌后,组才会被删除。后续添加或删除都将工作,但如果您没有删除旧的标记,一旦空白组不会删除自己,并再次返回0成功 - 0失败。
      在chrome中,行为就像在android中一样(token失效等)。


      因为我需要为android和web应用程序工作,我想通过跟踪登录时的令牌来区分web行为,把它放在一个表(user_id,reg_id)中。在每次登录时,我都会检查与用户相关的每个令牌是否仍然有效(向其发送通知并查看故障),以及如果将其从我的用户检索到的组名和组密钥的用户组中删除表。
      这将有很大的作用,使得有可能从群体中删除鬼币,如果不是这样的事实,在铬刷新令牌(Android类似),这意味着发送通知将返回失败,但与不同的错误(无效注册ID而不是未注册或类似的东西)。
      我可以进一步指定我的功能来完成他们所在浏览器的工作,或者只是检查错误类型,并明白是否必须从组中删除它,因为它是一个鬼令牌或只是从我的数据库删除行,因为它已经失效。
      那么,在那个时候,我真的厌倦了firebase团队糟糕的管理api,所以我选择了最简单的解决方案:什么也不做。

      这是一个功能强大的函数,在登录后执行,它将负责根据其名称对组进行ping操作(如问题的cURL命令中所述),如果错误发生,则创建组,如果返回通知密钥,则添加组。
      介意,甚至可以直接尝试创建组,并在出现错误的情况下,只需将设备添加到它,同样的事情。令牌会落在这两种情况下(失效或鬼魂),这意味着可能发生的最坏情况是当最后一个成员退出时团队不会死亡,太糟糕了。鬼令牌不应该加起来每组的设备的限制。



      悲伤,但容易和工作。
      如果任何人都可以看到所描述的任何缺点,我很乐意听到。


      I implemented the mapping between devices, registration ids, and groups as explained here

      Basically came up with a table where to store the device reg id and the notification key of the group to which it is registered (if any) , and added to my user table two fields to keep track of the number of devices that user has logged into and what is his pre determined group name.

      Unfortunately, while testing, I incurred into a very strange behavior when refreshing the token of a user, who is also the only member of a device group.

      as explained in the comments to the question i asked here

      if the previous token was the only member of a device group, after getting refreshed it is invalidated but the group keeps existing and somehow the new token gets added to it. i can even successfully remove the new token from the group thus deleting it, or i can notify the group "waking it up" and making it to auto remove itself

      in the couple of tries i have done right now before posting this is what happened:

      1. get a new token say reg_id1
      2. register reg_id1 to device group test_group (creating it)

      code to create group:

      curl --header "Authorization: your_key" 
      --header Content-Type:"application/json" 
      -H "project_id:your_id"   https://android.googleapis.com/gcm/notification 
      -d "{ \"operation\": \"create\", \"notification_key_name\": 
      \"test_group\", \"registration_ids\": [\"reg_id1\" ] }"
      

      1. test that the group exists

      with this

      curl -v -H "Content-Type:application/json" -H "Authorization:key=your_key" 
      -H "project_id:your_id"
      https://android.googleapis.com/gcm/notification?notification_key_name=test_group
      

      1. refresh reg_id1 with the way you prefer (deleting app data if on android or requesting new token if on web app )
      2. check what happened to the group with the command at point 3

      the group still exists (even if the only token there is now invalid)

      1. try deleting old token. what should happen? well, the answer is reasonable..the token we are trying to remove is not valid anymore

      code to remove

      curl --header "Authorization: key=your_key" 
      --header Content-Type:"application/json" -H "project_id:your_id" 
      https://android.googleapis.com/gcm/notification 
      -d "{ \"operation\": \"remove\", \"notification_key_name\": 
      \"test_group\", \"notification_key\": \"group_key\", 
      \"registration_ids\": [\"reg_id1\" ] }"
      

      1. Here comes the fun: try deleting the new refreshed token from the same group ! you will get a notification key in return , meaning that there were no errors..but wait ! how could it be?
      2. ping the group again with command at point 3 and.. the group still exists?! (previously, at the time of the problem in original question, while removing the new token from android, the group would cease to exist after this point..now with curl it continues living)
      3. try notifying the group then!

      code

      curl -X POST -H "your_key" 
      -H "Content-Type: application/json" 
      -d '{ 
      "notification": {
       "title": "Portugal vs. Denmark",
       "body": "5 to 1",
       "icon": "firebase-logo.png",
       "click_action": "http://localhost:8081"
      },
      "to": "group_key"
      }' "https://fcm.googleapis.com/fcm/send"
      

      1. what happens now is that you get 1 failure (which is ok) and if you try to ping the group again it will be magically disappeared..

      Sorry for being so long but i wanted to write all the steps so that you can reproduce the behavior easily.

      Can someone explain all of this? In my android app if the user deletes app data he will need to login again, since the creation/add to a device group is upon login, i need to delete the old token from the group (and delete the group if it was the last) so that he will be able to re-enter the group again (or create it). But i can't remove the old token directly because it is invalid. still, the group continues existing even if its only member is invalid. should i just notify it to wake it up and make it delete itself? should i remove the new token from the group as well ? (in android this would strangely lead to deleting the group)

      EDIT: after testing this morning i have a new use case:

      1. Create group with reg_id1 subscribed to it
      2. refresh reg_id1
      3. recreation of group says that group exists ( i can ping it ad receive a notification key in response)
      4. try to delete new token from group gives error 500
      5. notification test to the group gives 0 success and 0 failure
      6. try to remove old token from group gives back notification key (should be a positive answer)
      7. now group doesn't exist anymore

      EDIT2:

      after lots and lots of testing i came to these conclusions:

      • refreshing a token on android application invalidates it, if it was the only member of a device group, a simple notification to that group will wake it up and make it auto delete itself.
      • refreshing a token on a web application does not invalidate the token, if it was the only member of a device group, notifying the group will result in a 0 success 0 failure. while being invisible the token is still registered to the group and the group will cease to exist only when the old token will be removed. in this case, even if still there the old token won't concur to the limit of 20 devices ( i successfully registered and refreshed 25 tokens to the same group). What is needed now is a way to retrieve the old token to remove it from the group , in a web application scenario. this is crucial since a web application doesn't have a unique id therefore it can't be mapped as in android (with the android id) to the registration token, and the old token won't even appear as a failure when notifying, meaning that it's almost impossible to retrieve it after it was refreshed.

      解决方案

      This is what i ended up doing. it's by no means elegant, and i had to compromise between what i need and what actually happens.

      First of all i confirm that:

      1. In android , when a token gets refreshed it is invalidated, therefore automatically eliminated from every group it was part of (not instantaneously, more like at the first notification or operation of add/removal on the group). This is why a simple notification (not dry_run though) would serve as wake up for the group, meaning that if it was the last member, the group would immediately die. Notice that even if the token gets invalidated, in the case it was the last member of the group, the group continues to exist! a notification would wake it up and kill it, but otherwise adding more devices would still work!

      2. On a webapp instead, the behavior is much more complex because it is browser dependent (surprise?). for example in Firefox the refreshed token magically disappears, but doesn't get invalidated. meaning that if it was the only member of a group, sending a notification to that group will result in 0 success and 0 failures, only after removing that old token from the group, the group will get deleted. Subsequent adding or removal would all work, but if you didn't remove the old token, once empty the group would not delete itself and return again 0 success - 0 failures. In chrome instead, the behavior is like in android (token invalidated etc. ).

      Since i needed something working for both android and web app i thought about differentiating the web behavior by keeping track of the token upon login , putting it in a table (user_id, reg_id). at every login i would check if every token associated with the user was still valid (sending a notification to it and looking at the failures) and in case, delete it from the user group whose group name and group key i would retrieve from my user table. This would have greatly worked, making it possible to remove ghost tokens from groups , if not for the fact that in chrome the tokens get invalidated when refreshed (android-like), meaning that sending a notification would return a failure but with different error ("invalid registration id" instead of " not registered" or something like that). I could have further specified my functions to do their work with respect to the browser they were in , or maybe just check the error type and understand if i had to delete it from the group because it was a ghost token or just delete the line from my db because it had been invalidated. Well, at that point i was really fed up with the poor management api of firebase's groups, therefore i chose the simplest solution: do nothing.

      I concocted a powerful function, to be executed after login , that would take care of pinging a group by its name (as explained in the question's cURL commands) and either create the group if error or add to the group if a notification key was returned. Mind that one could even directly try to create the group, and in case of error just add the device to it, same thing.

      the refresh of a token would fall in those two scenarios (invalidated or ghost), meaning that the worst that could happen is the group not dying when the last member exited, too bad. ghost tokens shouldn't add up to the limit of devices per group.

      Sad, but easy and working. If anyone can see any downside to doing as described, i would love to hear about it.

      这篇关于刷新设备组的唯一成员用户的令牌时出现意外的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆