Reputation: 509
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:
reg_id1
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\" ] }"
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
reg_id1
with the way you prefer (deleting app data if on android or requesting new token if on web app )the group still exists (even if the only token there is now invalid)
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\" ] }"
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"
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:
EDIT2:
after lots and lots of testing i came to these conclusions:
Upvotes: 3
Views: 607
Reputation: 509
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:
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!
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.
Upvotes: 3