4

I'm going to develop an app that uses device groups feature. As I understand I need to first send current registration token I get on Android client in method onTokenRefresh to the server and then add this registration token to proper device group (or create it if it doesn't exist) via HTTP request. I see, however, a potential for leaking registration tokens, as Android app user may for example wipe app's data multiple times. How to prevent it? What happens when a limit of 20 members is exceeded? And is it possible to check whether some group already exists or not?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Matis
  • 503
  • 5
  • 17
  • 1
    Cross-post: https://groups.google.com/d/msg/firebase-talk/B8wG6CMC8lA/X6KvwaydAwAJ – Frank van Puffelen Jun 28 '16 at 15:00
  • After 4 months do you have any progress? I would like to know how should you handle expired tokens in device groups; you should somehow uniquely identify the device... – Galya Oct 06 '16 at 12:24
  • 1
    @Galya I decided not to use device groups, I simply use topics with user id in them. – Matis Oct 09 '16 at 07:23
  • @Matis According to [this post](http://stackoverflow.com/a/42291098/4218640) creating topis per user id is not a good idea. – ElectroBuddha Mar 09 '17 at 00:42

2 Answers2

2

I see, however, a potential for leaking registration tokens, as Android app user may for example wipe app's data multiple times. How to prevent it?

If by preventing you mean disabling Clear Data for your app in the App Manager, you should refer to this post. The accepted answer states that it isn't possible.

However, Jakar's answer provides a workaround where instead of Clear Data, Manage Spaces will show up instead. Haven't tried it out yet, so I can't say for sure. The upvotes speak for itself though.

But, if ever the app's data is wiped/cleared by the user, you should refer with what is stated in the FirebaseInstanceId docs:

Instance ID is stable except when:

  • App deletes Instance ID

  • App is restored on a new device

  • User uninstalls/reinstall the app

  • User clears app data

In the above cases a new Instance ID is generated and the application needs to recreate the authorization tokens previously generated implementing onTokenRefresh().


What happens when a limit of 20 members is exceeded?

Not sure what the question is here.. But if you are pertaining to adding devices to a Device Group more than the maximum...

Wasn't able to find it clearly stated in the FCM: Device Group Messaging docs, but if you refer to the Add to group section, it states:

A successful operation returns a notification_key.

So from that, I think if you ever try to add another device to an already maxed out device group, the operation will fail.

I suggest using Topics instead, if you think you're going more than 20. But I don't really know what your use-case is, so.. your call.


And is it possible to check whether some group already exists or not?

For this, you should make use of the notification_key and notification_key_name. As per the docs:

The notification_key_name is a name or identifier (e.g., it can be a username) that is unique to a given group. The notification_key_name and notification_key are unique to a group of registration tokens. It is important that notification_key_name is unique per client app if you have multiple client apps for the same sender ID. This ensures that messages only go to the intended target app.

And emphasizing on the statement:

Basic management of device groups — creating and removing groups, and adding or removing devices — is usually performed via the app server.

The keys and names should be on your server, so that you can check if it already exists or not.

Community
  • 1
  • 1
AL.
  • 36,815
  • 10
  • 142
  • 281
  • 2
    By "preventing" I meant preventing the registration ID leak. Wiping app data was just an example how to quickly leak those - if a new token is assigned and old one is not removed then we have a leak. – Matis Jun 29 '16 at 08:32
  • I see. -- *if a new token is assigned and old one is not removed then we have a leak* -- Isn't that simply handled on your server side? Making use of the Canonical Ids? Other scenarios should be handled in the client app itself? – AL. Jun 29 '16 at 08:39
  • 3
    Canonical IDs may be a solution, but they aren't clearly mentioned in FCM docs (only GCM). (There is a mention on https://firebase.google.com/docs/cloud-messaging/server#response, but it doesn't explain why or when these canonical IDs are returned). But I want to use device groups, so I operate on individual device's registration ID only when adding it to a group. I'd also like to clarify my last question: I know I need to store groups on my app's server, but sometimes they may get out-of-sync with FCM servers, that's why I'd like to check if a group with given `notification_key_name` exists. – Matis Jun 29 '16 at 09:26
  • I'm also interested in knowing how canonical ids are to be used in device group messaging. Or does the FCM server automatically use canonical ids in case of device groups? – Sreekanth Jul 27 '16 at 10:53
2

I am currently doing the following with some success but not fully tested or scaled yet.

App uses firebase as the backend and I am adding FCM to implement push notifications.

I need groups to handle when a user could be on different devices or several devices.

I store the returned notification_key value and the registration_id (token) for each device with the profile i.e

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

When a user first signs on there is no data under the FCM node i.e. no notification_key and no registration_ids

Each time a user signs in they hook up to their profile_id.

I get the FCM token and then

If there is no notification_key (i.e. first time on any device) I create the group using the profile_id as the notification_key_name and store the notification_key that comes back.

If there is a notification_key (return sign-in or first sign-in on a new device) I see if there is a registration_id for the current device and if not (first sign-in on new device), add the device_uuid:token pair to the registration_ids.

If there is (return sign-on) I remove the stored token from the FCM group and replace the old token in my stored registration_ids with the token I just got.

I can now message all of the devices used by that user (profile) by sending to their profile_id, and I shouldn't be leaking tokens because I delete the old ones.

However, I have no way of knowing because there doesn't seem to be API to just read the group and the tokens so that the groups could be cleaned every now and again.

Also, my early code bugged and I didn't capture the notification_key so now I can't add, remove or do anything to one of my groups. I hate the idea that I'll have to leave burned groups lying around in the firebase cloud for ever and ever.

I think FCM should provide more API access to help us keep the place tidy.

blythburgh
  • 93
  • 5
  • I am following almost same approach, I have a question. FCM automatically deletes the Device Group if there aren't any devices associated with it are left. How do you handle this case? As per my understanding if a token is not longer valiid its automatically removed from the group in FCM. – Naveed Ahmed Dec 15 '16 at 15:15
  • When I remove a token from the group because its been replaced on my device, if it is the last/only token then the FCM group gets deleted and I get an error when I try to register the new token. I trap the error by its text message i.e. "notification_key not found" and call my create_group function upon it so that it remakes a new group with the same notification_key as before and adds the token to it. This is feels a bit hacky but in a similar way, I also use error text "notification_key already exists" as a condition to register an additional token for a new device. – blythburgh Dec 18 '16 at 21:02
  • Yes, this is how I am handling it now, but I was wondering if there is some better approach since this feels a bit hacky. – Naveed Ahmed Dec 18 '16 at 21:58
  • Until there are group_exists(group) and token_exists(group,token) type API calls with bona fide true/false success callbacks, I don't think there is. – blythburgh Dec 19 '16 at 22:17
  • So glad to find out I am not alone.... capturing the error is my method to determine whether I need to add a token to a group or create a group in some circumstances as well. I also think it is hacky. – Phillip Stack Jan 16 '17 at 16:45
  • @blythburgh How do you set yours "device_1_uuid"? Are you using hardware device ID (like IMEI) ? (I would like to avoid to use such kind of ID but I don't see any other solution to have un unique deviceID (to map with user and FCM registrationID) – ThierryC Mar 13 '17 at 14:42
  • Yes I use the hardware uuid. I obtain it using the ngCordova plugin $cordovaDevice. It has a .getUUID() method. This works for me on ios. I haven't tested android yet. I capture the uuid to the rootScope as soon as the device is ready and its then examined in a number of places across the app for different purposes, push notifications being just one of them. – blythburgh Mar 14 '17 at 22:52