I got a question about Google Cloud Messaging...
I send GCM to Google for 3 Registration IDs, then Google replies that 2 of the Registration IDs has been sent successfully and one not, because the Registration ID was wrong!
But it doesn't tell me which Registration ID has not been sent...
Now here's my question:
how can I parse the Google GCM response to get that which Registration ID has not been sent? Does Google has an API or something so that I can give it "multicat_id" and it tells me which Registration ID had a problem?
Any help would be so much appreciated, I'm just so confused :)
It's based on the order :
Suppose you send this :
{ "collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
And get this response from Google :
{ "multicast_id": 216,
"success": 3,
"failure": 3,
"canonical_ids": 1,
"results": [
{ "message_id": "1:0408" },
{ "error": "Unavailable" },
{ "error": "InvalidRegistration" },
{ "message_id": "1:1516" },
{ "message_id": "1:2342", "registration_id": "32" },
{ "error": "NotRegistered"}
]
}
This means that the 3rd registration ID that you sent (15) is invalid and the 6th (42) is not registered. Both should be removed from your DB.
Here's how I did it:
$gcm_result = $gcm->send_notification($registration_ids, $message);
$jsonArray = json_decode($gcm_result);
if(!empty($jsonArray->results)){
$remove_ids = array();
for($i=0; $i<count($jsonArray->results);$i++){
if(isset($jsonArray->results[$i]->error)){
if($jsonArray->results[$i]->error == "NotRegistered"){
$remove_ids[$i] = "'".$registration_ids[$i]."'";
}
}
}
if(!empty($remove_ids)){
$remove_ids_string = implode(', ',$remove_ids);
include_once SCRIPTS.'gcm_server_php/db_functions.php';
$dbf = new DB_Functions();
$res = $dbf->deleteUsers($remove_ids_string);
echo count($remove_ids)." users have unregistered from notifications since the last one was sent out.";
}
}
Based on what I read here:
http://developer.android.com/google/gcm/http.html#error_codes
http://developer.android.com/google/gcm/server-ref.html#error-codes
I've developed as follows (not tested yet):
$result = $gcm->send_notification($registration_ids, $message);
$jsonArray = json_decode($result);
if($jsonArray->canonical_ids != 0 || $jsonArray->failure != 0){
if(!empty($jsonArray->results))
{
for($i = 0 ; $i<count($jsonArray->results) ; $i++){
$result = $jsonArray->results[$i];
if(isset($result->message_id) && isset($result->registration_id))
{
// You should replace the original ID with the new value (canonical ID) in your server database
}
else
{
if(isset($result->error))
{
switch ($result->error)
{
case "NotRegistered":
case "InvalidRegistration":
// You should remove the registration ID from your server database
break;
case "Unavailable":
case "InternalServerError":
// You could retry to send it late in another request.
break;
case "MissingRegistration":
// Check that the request contains a registration ID
break;
case "InvalidPackageName":
// Make sure the message was addressed to a registration ID whose package name matches the value passed in the request.
break;
case "MismatchSenderId":
// Invalid SENDER_ID
break;
case "MessageTooBig":
// Check that the total size of the payload data included in a message does not exceed 4096 bytes
break;
case "InvalidDataKey":
// Check that the payload data does not contain a key that is used internally by GCM.
break;
case "InvalidTtl":
// Check that the value used in time_to_live is an integer representing a duration in seconds between 0 and 2,419,200.
break;
case "DeviceMessageRateExceed":
// Reduce the number of messages sent to this device
break;
}
}
}
}
}
}