Canonical Registration Id and Message Id Format

Neither old or new registration id is canonical

This was a bug in gcm which is now fixed.

Now if I send notification to old gcm id, it returns the new registration id as canoncial id.

Source: https://github.com/google/gcm/issues/94

Android using Canonical ID GCM

Yes. You can use canonical IDs to help you more easily recover from your errors. It is the registration token of the last registration requested by the client app. This is the ID that the server should use when sending messages to the device.

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

Based from this blog, GCM service returns the cannonical IDs in the order notifications were sent. Here is a sample response:

{
"multicast_id": 7036866281258904189,
"success": 1,
"failure": 0,
"canonical_ids": 1,
"results": [
{
"registration_id": "CANNONICAL_REGISTRATION_ID",
"message_id": "0:1415529915241995%64ac3713f9fd7ecd"
}
]
}

The canonical id = 0 means that registration id which your push sever used is OK and not should be replaced by canonical id, i.e. often GCM server will be response canonical_id = 0.
In the example response there's one cannonical id and it means that your server has to replace existing registrtation id on new value which you see in response. This case easy reproduce if user reinstall your client application, but your push server doesn't know about it and GCM server will pass in response new registration id.

Check these related SO questions about Canonical IDs:

  • How to get Canonical ID from GCM
  • Get GCM canonical registration ID without sending a message

Get GCM canonical registration ID without sending a message

You can specify "dry_run": true option in /send request.

I found that devices do not receive any push notifications with "dry_run": true option, while a server get canonical_ids response.

Here is a sample code in Ruby. You may have to install gcm Gem beforehand.

$ gem install gcm

ask_canonical_ids.rb

require 'gcm'
require 'json'

API_KEY = "YourApiKey"
gcm = GCM.new(API_KEY)

registration_ids = [
'OldRegistrationId',
]

option = { data: { 'message' => 'Hello Gcm!' }, dry_run: true }
response = gcm.send_notification(registration_ids, option)

p response[:canonical_ids]

output of $ ruby ask_canonical_ids.rb (formatted)

[{
:old => "OldRegistrationId",
:new => "NewRegistrationId"
}]

Again, your device will not receive any push notifications.

CM getting Canonical ID

Here's an example of how the response is parsed by Sender.java in sendNoRetry method :

   try {
BufferedReader reader =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
try {
String line = reader.readLine();

if (line == null || line.equals("")) {
throw new IOException("Received empty response from GCM service.");
}
String[] responseParts = split(line);
String token = responseParts[0];
String value = responseParts[1];
if (token.equals(TOKEN_MESSAGE_ID)) {
Builder builder = new Result.Builder().messageId(value);
// check for canonical registration id
line = reader.readLine();
if (line != null) {
responseParts = split(line);
token = responseParts[0];
value = responseParts[1];
if (token.equals(TOKEN_CANONICAL_REG_ID)) {
builder.canonicalRegistrationId(value);
} else {
logger.warning("Received invalid second line from GCM: " + line);
}
}

Result result = builder.build();
if (logger.isLoggable(Level.FINE)) {
logger.fine("Message created succesfully (" + result + ")");
}
return result;
} else if (token.equals(TOKEN_ERROR)) {
return new Result.Builder().errorCode(value).build();
} else {
throw new IOException("Received invalid response from GCM: " + line);
}
} finally {
reader.close();
}
} finally {
conn.disconnect();
}

As you can see, the canonical registration ID is searched for in the second line of the response, but only if the first line of the response contains message ID.

android GCM get original id of canonical id

As described in the post that you linked to, it's all based on the position in the response list. So when you get the canonical ID you need to update the original registration ID in the same position of your "send list".

So in your example here are the results 4 of which are canonical (0, 3, 4, 5):

[0] {"registration_id":"3","message_id":"m1"},
[1] {"message_id":"m1"},
[2] {"message_id":"m1"},
[3] {"registration_id":"3","message_id":"m1"},
[4] {"registration_id":"3","message_id":"m1"},
[5] {"registration_id":"3","message_id":"m1"}

And here is your "send list":

[0] "1",
[1] "2",
[2] "3",
[3] "4",
[4] "5",
[5] "6"

According to the results you need to update the registration ID's in position 0, 3, 4, 5 to the ID of 3. That means that you will end up with a registration list like the following:

[0] "3",
[1] "2",
[2] "3",
[3] "3",
[4] "3",
[5] "3"

And finally:

[0] "3",
[1] "2",

Also see: https://developer.android.com/google/gcm/adv.html#canonical and https://developer.android.com/google/gcm/gcm.html#response

Reproduce canonical Id as 1 in send notification using GCM

Steps to produce Canonical error while sending notification using GCM

  • The initial state : Application is installed on Android device and is registered to GCM. Sender server has the registration Id and manages to send messages to that device.

  • Uninstall the application.

  • Send two messages to the original (old) registration Id. The first will seem to work (server will receive a successful reply from GCM server). The second attempt will result in a "NotRegistered" error.

  • Re-install the application and register to GCM. The device will get a new registration Id.

  • Send a message using the old registration Id. The application will receive the message, but the server will get in the reply the new registration Id as canonical registration Id.

Source : https://stackoverflow.com/a/12978274/2189626



Related Topics



Leave a reply



Submit