Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Canonical ID from GCM

I am trying to get a unique ID for my device so I can get push notifications from my server.

As all turorials say : I register using GMC:

  GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
  String regid = gcm.register(PROJECT_NUMBER);  // <---- duplicated if uninstalled/ reinstalled
  SendRegIdToServer(regId);

Now, I send the regId my server and save on device.

The problem comes when I uninstall and reinstall, since the local storage is lost, I ask GCM to register again and I get a new registration ID. Because of this, my server is having duplicates of the same device.

I looked at SO butlot of questions are on GCMRegistrar, which is deprecated now. People say use Canonical ID, which is unique. But how do I get it ?

I am using gcm.register and using that ID, which obviously is duplicating on the server.

Appreciate any help.

like image 782
techtinkerer Avatar asked Nov 22 '14 00:11

techtinkerer


1 Answers

The Canonical id is returned in the response when you send a message from your server to google's gcm server.

https://developer.android.com/google/gcm/http.html#response

Interpreting a success response

When a JSON request is successful (HTTP status code 200), the response body contains a JSON object with the following fields:

Field Description multicast_id Unique ID (number) identifying the multicast message. success Number of messages that were processed without an error. failure Number of messages that could not be processed. canonical_ids Number of results that contain a canonical registration ID. See Advanced Topics for more discussion of this topic. results Array of objects representing the status of the messages processed. The objects are listed in the same order as the request (i.e., for each registration ID in the request, its result is listed in the same index in the response) and they can have these fields: message_id: String representing the message when it was successfully processed. registration_id: If set, means that GCM processed the message but it has another canonical registration ID for that device, so sender should replace the IDs on future requests (otherwise they might be rejected). This field is never set if there is an error in the request. error: String describing an error that occurred while processing the message for that recipient. The possible values are the same as documented in the above table, plus "Unavailable" (meaning GCM servers were busy and could not process the message for that particular recipient, so it could be retried). If the value of failure and canonical_ids is 0, it's not necessary to parse the remainder of the response.

Update

Below is some more info on Canonical IDs. Basically, if somehow the device reg id becomes out of sync with what Google thinks it should be, then when your server sends a request with the out-of-sync id, the gcm server will include in it's response , the correct id to be used in the future.

Think about it, the way this works is; your server should have stored the reg id when the device registered with gcm. Your server sends a request to gcm with that id, gcm uses that id to send a message to your device. GCM can't the reg id on your device without telling the server about it. If it did your server would just keep sending the wrong reg id. Instead, gcm tell the server that the reg id it is using for a particular device is bad, your server can then send a message to the device to update its stored reg id to what it should be, and then the device can ack the change in REG IDs. The info below implies there is some time limit as too how long the "bad" id can still be used to send messages. I think the assumption is that it should be long enough for your server to change the device id (via a gcm message using the "bad" id)

Canonical IDs

On the server side, as long as the application is behaving well, everything should work normally. However, if a bug in the application triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages.

GCM provides a facility called "canonical registration IDs" to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your application. This is the ID that the server should use when sending messages to the device.

If later on you try to send a message using a different registration ID, GCM will process the request as usual, but it will include the canonical registration ID in the registration_id field of the response. Make sure to replace the registration ID stored in your server with this canonical ID, as eventually the ID you're using will stop working.

like image 150
nPn Avatar answered Oct 20 '22 10:10

nPn