I've got a server app that sends GCM push notifications. Each send of 1000 recipients returns a message that tells me the status of each registration ID. Some will have error codes. Is there a document somewhere from Google that tells me how I'm expected to handle these codes and what all the possible error codes are? My Google foo isn't turning up anything.
You didn't look hard enough. All the codes are explained here under Interpreting an error response.
I tried to copy and paste it in order for it not to be a link only answer, but the formatting is a bit off:
Interpreting an error response
Here are the recommendations for handling the different types of error
that might occur when trying to send a message to a device:
Missing Registration ID
Check that the request contains a registration ID (either in the registration_id parameter in a plain text message, or in the
registration_ids field in JSON).
Happens when error code is MissingRegistration.
Invalid Registration ID
Check the formatting of the registration ID that you pass to the server. Make sure it matches the registration ID the phone receives in
the com.google.android.c2dm.intent.REGISTRATION intent and that you're
not truncating it or adding additional characters.
Happens when error code is InvalidRegistration.
Mismatched Sender
A registration ID is tied to a certain group of senders. When an application registers for GCM usage, it must specify which senders are
allowed to send messages. Make sure you're using one of those when
trying to send messages to the device. If you switch to a different
sender, the existing registration IDs won't work. Happens when error
code is MismatchSenderId.
Unregistered Device
An existing registration ID may cease to be valid in a number of scenarios, including:
If the application manually unregisters by issuing a com.google.android.c2dm.intent.UNREGISTER intent.
If the application is automatically unregistered, which can happen (but is not guaranteed) if the user uninstalls the application.
If the registration ID expires. Google might decide to refresh registration IDs.
If the application is updated but the new version does not have a broadcast receiver configured to receive com.google.android.c2dm.intent.RECEIVE intents.
For all these cases, you should remove this registration ID from the 3rd-party server and stop using it to send messages.
Happens when error code is NotRegistered.
Message Too Big
The total size of the payload data that is included in a message can't exceed 4096 bytes. Note that this includes both the size of the
keys as well as the values.
Happens when error code is MessageTooBig.
Invalid Data Key
The payload data contains a key (such as from or any value prefixed by google.) that is used internally by GCM in the
com.google.android.c2dm.intent.RECEIVE Intent and cannot be used. Note
that some words (such as collapse_key) are also used by GCM but are
allowed in the payload, in which case the payload value will be
overridden by the GCM value.
Happens when the error code is InvalidDataKey.
Invalid Time To Live
The value for the Time to Live field must be an integer representing a duration in seconds between 0 and 2,419,200 (4 weeks).
Happens when error code is InvalidTtl.
Authentication Error
The sender account that you're trying to use to send a message couldn't be authenticated. Possible causes are:
Authorization header missing or with invalid syntax.
Invalid project number sent as key.
Key valid but with GCM service disabled.
Request originated from a server not whitelisted in the Server Key IPs.
Check that the token you're sending inside the Authorization header is the correct API key associated with your project. You can
check the validity of your API key by running the following command:
api_key=YOUR_API_KEY
curl --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send -d "{\"registration_ids\":[\"ABC\"]}"
If you receive a 401 HTTP status code, your API key is not valid. Otherwise you should see something like this:
{"multicast_id":6782339717028231855,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
If you want to confirm the validity of a registration ID, you can do so by replacing "ABC" with the registration ID.
Happens when the HTTP status code is 401.
Timeout
The server couldn't process the request in time. You should retry the same request, but you MUST obey the following requirements:
Honor the Retry-After header if it's included in the response from the GCM server.
Implement exponential back-off in your retry mechanism. This means an exponentially increasing delay after each failed retry (e.g.
if you waited one second before the first retry, wait at least two
second before the next one, then 4 seconds and so on). If you're
sending multiple messages, delay each one independently by an
additional random amount to avoid issuing a new request for all
messages at the same time.
Senders that cause problems risk being blacklisted.
Happens when the HTTP status code is between 501 and 599, or when the error field of a JSON object in the results array is
Unavailable.
Internal Server Error
The server encountered an error while trying to process the request. You could retry the same request (obeying the requirements
listed in the Timeout section), but if the error persists, please
report the problem in the android-gcm group.
Happens when the HTTP status code is 500, or when the error field of a JSON object in the results array is InternalServerError.
Invalid Package Name A message was addressed to a registration ID whose package name did not match the value passed in the request. Happens when error code is InvalidPackageName.
EDIT (06/06/2015) :
A new error response codes table has been posted here.
The new error responses :
Device Message Rate Exceeded The rate of messages to a particular device is too high. Reduce the number of messages sent to this device and do not immediately retry sending to this device.
Topics Message Rate Exceeded The rate of messages to subscribers to a particular topic is too high. Reduce the number of messages sent for this topic, and do not immediately retry sending.
EDIT (07/21/2019) :
A new error response codes table has been posted here.
Related
Recently I migrated from GCM to FCM for sending the notification via my app, i want to know whether can able to subscribe the members in particular topic from my app server. If possible, then how will find out if a particular member token valid or expired.
Because in my database, i have near to 22L people GCM Registration TOKEN id, so that i will create one topic and subscribe those members via my app server.
Any ideas to resolve this kind of issues.
You can subscribe multiple tokens to Topic via your App Server using the Instance ID API, specifically, using batchAdd. It can also identify if the Registration Token that you were subscribing is invalid by returning a NOT_FOUND error. From the docs:
Manage relationship maps for multiple app instances
Using the Instance ID service's batch methods, you can perform batch management of app instances. For example, you can perform bulk addition or removal of app instances to an FCM or GCM topic. To manage app instances, call the Instance ID service at this endpoint, providing the app instance tokens in the JSON body:
https://iid.googleapis.com/iid/v1:batchAdd
https://iid.googleapis.com/iid/v1:batchRemove
Parameters
Authorization: key=YOUR_API_KEY. Set this parameter in the header.
to : The topic name.
registration_tokens : The array of IID tokens for the app instances you want to add or remove.
Results
On success the call returns HTTP status 200. Empty results indicate successful subscription for the token. For failed subscriptions, the result contains one of these error codes:
NOT_FOUND — The registration token has been deleted or the app has been uninstalled.
INVALID_ARGUMENT — The registration token provided is not valid for the Sender ID.
INTERNAL — The backend server failed for unknown reasons. Retry the request.
TOO_MANY_TOPICS — Excessive number of topics per app instance.
Example POST request
https://iid.googleapis.com/iid/v1:batchAdd
Content-Type:application/json
Authorization:key=API_KEY
{
"to": "/topics/movies",
"registration_tokens": ["nKctODamlM4:CKrh_PC8kIb7O...", "1uoasi24:9jsjwuw...", "798aywu:cba420..."],
}
Example result
HTTP 200 OK
{
"results":[
{},
{"error":"NOT_FOUND"},
{},
]
}
If I send push message by selecting a package from Firebase console, the push goes to all devices, but during sending to individual device, it displays the error:
Invalid reg token,please check token format
Error Snapshot:
UserID in console is not the registration token for Firebase messaging. By Firebase docs:
on initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseInstanceIdService.
My last registration token looks like
cpeBAc1NkUE:APA91bEpAKHQTdgkWVdDzDZG8BPon0APaIhbbuSejDpZF-FO1gD2saDV7_EQDo2WEz0H6e5U-uf0i-v4b25NXgGzV2oUrNuboM5675WY7VCP3JcBl8BCNY7eV0VFGHT9oRox0EEoo_ch
In the other answer, you mentioned in the comments that you're Registration Token is:
cbuJIjkg9zQ%3AAPA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cPiTQINykKjrLf8E0qEwJj3XmJ1IoTmn0r2EoLR_mAHGOjlA61CnQ8aSn2WxWKKByOwbsnqoVeaeWQIeGU_yh4wnZ67soLtI
I noticed the % (percentage character) included in it, which isn't a usual character included in registration tokens. Figured that it was possible that this was encoded somehow. When decoded, this is the value:
cbuJIjkg9zQ:APA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cPiTQINykKjrLf8E0qEwJj3XmJ1IoTmn0r2EoLR_mAHGOjlA61CnQ8aSn2WxWKKByOwbsnqoVeaeWQIeGU_yh4wnZ67soLtI
Notice that the %3A was turned into : (colon). This is one of the usual characters. So I would suggest that you try the value above.
And as a reminder, the InvalidRegistration error (emphasis mine):
Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with Firebase Notifications. Do not truncate or add additional characters.
Don't even encode it. Use it as is. Also, do note that the Registration Token should be kept secret.
We use GCM messaging to send remote commands to device. We have one particular client who uses the same model of devices from one manufacturer and with has 5.1 OS.
Our client registration process is pretty standard, that is once the client logs-in, it updates the GCM-Id to server and on server we have some commands that can be sent to the registered devices and internally it uses the registration id.
We are observing that even if the remote command is sent to one of the devices, it is being delivered to all these devices. The GCM Id on all these devices is different.
This does not happen with other devices (or we have not seen it yet)
If we use FCM Diagnostics and verify the lifecycle of message using the GCM-Ids of these devices we see that the same message ID has been delivered to all these devices.
We made sure that there is no ghost or random delivery from our backend, we verified backend logs and added extra logging as well.
Request for tips or hints, if anybody else saw such an issue earlier.
Try see this git on line 57, he uses json to sent a single message to multiples registration ids.
Example json content:
{
"data":
{
"from": "my_name",
"time": "0:56:23"
},
"registration_ids": ["id_1", "id_2", "id_3", "id_4"]
}
Lucas is correct in his example, the registration_ids is a parameter that specifies a list of devices (registration tokens, or IDs) receiving a multicast message. It can contain at least 1 and at most 1000 registration tokens.
Note: registration_ids are only for multicast messaging, not for
single recipients. Multicast messages (sending to more than 1
registration tokens) are allowed using HTTP JSON format only.
For more information, check this documentation.
i got confused by gcm today. I dont know if my registrationid is correct. I got characters and a colon in front of a registrationid starting with APA. The Pattern is xXXXxxX:APA... . I implemented google cloud messaging for a android client using the example from here: https://developers.google.com/cloud-messaging/android/client . If i use a older implementation (for example with GCMRegistrar) i only get a registration id starting with APA. Till now i though a registration id has to start with APA.
Is the stuff before the colon some tokenspecific stuff? Do i have to pass the full token to the webservice or is it okay if i cut the chars before the colon and send the registration starting with APA?
GCM Registration Token is equal to registration_id. As I mentioned in my answer here:
An FCM Token, or much commonly known as a registrationToken like in google-cloud-messaging. As described in the GCM docs:
An ID issued by the GCM connection servers to the client app that allows it to receive messages. Note that registration tokens must be kept secret.
Different terms point to the same thing. The format for the registration token may also vary as seen this answer:
The GCM registration token is usually around 140 chars in length, and can contain colons, underscores and hyphens. Maximum size is supposed to be 4k.
Though I'm not entirely sure with regards to the character length, I think I've read on a post here somewhere that it may exceed that number. Do search around.
gcm.register() is deprecated. use instance id method with token instead.
https://developers.google.com/cloud-messaging/android/legacy-regid
GCM register() is deprecated starting May 28, 2015. New app
development should use the Instance ID API to handle the creation,
rotation, and updating of registration tokens. For more information,
see Registering Client Apps and Set up a GCM Client App on Android.
I have successfully implemented everything related to GCM but this one last thing is giving me trouble. Simply, I want to stop sending to devices that no longer have app - remove their registration IDs.
The problem is that I am using registration_ids variable that allows sending to multiple devices at once. I could possibly send 1 by 1 and then I would obviously know which devices to remove. I have isolated sending to 2 DeviceIds - one is registered and one is not. Sure enough here is the response I get from Google:
{
"multicast_id":4688510806873974237,
"success":1,
"failure":1,
"canonical_ids":0,
"results":[
{"error":"NotRegistered"},
{"message_id":"0:1459152002041797%5c073a337cbfbb56"}
]
}
How can I deduce from that response which devices I need to unregister from future GCM pushes?
While typing question and formatting response JSON I've noticed that results array has error field for first registration. After reading GCM reference page in more detail it seems that you'll get entry in results for each message sent.
So in my case, I have "failure":1 and then for first message in results I got {"error":"NotRegistered"} and that can tell me I need to remove that device from senders list.
In case you are wondering canonical_ids is for case when device id needs to be updated in your database, in case where that is canonical_ids > 0 you'll get registration_id in results array.