My question is this I implementing a system to clear our servers of expired GCM registration tokens.
Once a registrationID is rejected by GCM as not registered or expired can it ever become valid again ? For APNS in iOS this can occur, but it cannot happen for GCM correct?
Once a client updates its registration tokens with GCM and our servers try to send notifications downstream it can receive a result with a canonical ID listing the new registration ID. How long is the old registration ID valid?
Yes. Once the token expires, a different valid token takes it's place --
triggering onTokenRefresh() on the corresponding client's side. It's actually expected for the developers to immediately remove the expired token from where they keep it, and replace it with the new one.
Canonical IDs are AFAIK, no longer used.
Related
I wonder what is the lifecycle of registrationId(device_token)
e.g eD3Fa1yVqx8:APA91bH5gNrC-jhUqaoRwyFLfD2ik4NXwCXohwhm_9CM5hnY9wFwUAOiO_O12Or-dm60sUqy9gN2ZW6mw5i90RyNhb-zHilvtcJczPjZoQlm_4lKNKDejC_1_xiqmYoZnSxaFfVqSA1d
How to handle the situation if it's changed?
As far as the information on the official docs goes, there is no information about the token being changed by Google. However you should change it periodically.
Quoting https://developers.google.com/cloud-messaging/registration#automatic-retry-using-exponential-back-off
Keeping the Registration State in Sync
To protect the client app and app server from potential malicious
re-use of registration tokens, you should periodically initiate token
refresh from the server. When GCM registration token refresh is
initiated from server side, the client app must handle a
tokenRefreshed message with the GCM registration client/server
handshake.
I faced some situations where Registration ID changed. But, i don't know how and when.
So, to handle these situations i updated my app to send Registration ID every time the app is launched. I sent Registration ID with device id and check my database if the registration id changed i updated it.
I have questions. How can I handle situation when GCM return canonical id.
I found few same questions on StackOverflow, but there is no solution. Amazon SNS Documentation about token management says that SNS handle this situation automatically. When GCM return canonical id amazon SNS update old tokens with new ones. But how can I know about that? I have my own database with all registered token and endpoints. I don't know if amazon was update token or not and send notification to all of them. As result lots of duplicate messages on device.
P.S. Server have to support multiple devices for one account.
Amazon SNS will handle token management only if your app is registered with them. Since you have your own database and endpoints, you would have to manage it yourself.
After pushing the message from the server, you would recieve the canonical id in the response.
As per Google's docs,
A canonical registration ID 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.
It is good practice to update your registration id with the canonical id returned after the push.
Also if your device is receiving duplicate notifications these could help:-
It could be due to a bug in the client app triggering multiple registrations for the same device. So make sure the same device is not getting registered many times.
Also, if you uninstall the app from device and you try to send a push to that device, you would get a NotRegistered error from GCM server. Then your server should delete the registration token and not use that registration token again to push messages.
P.S. Even if one user has multiple devices, your db mappings should be such that :- each device of the user will have a different registration token and each of the tokens will be mapped to a single user.
Since the tokens are different, receiving the same message pushed on all devices of the user would not be a problem.
Hope this helps! Cheers!
Please take a look at http://mobile.awsblog.com/post/Tx223MJB0XKV9RU/Mobile-token-management-with-Amazon-SNS for information on how to manage the mobile tokens.
When do orphaned GCM Registration IDs expire?
Steps to reproduce:
gcm.register(gcmSenderId) and receive a Registration ID
Verify receipt of push notifications
Factory Reset
gcm.register(gcmSenderId) and receive a Registration ID
Verify receipt of push notifications
Now, however, you can still send to the old Registration ID and receive "success:1". When, if ever, does that Registration ID expire and under what circumstances?
Registration ID generate using this Instance ID API
The client app obtains registration token using the Instance ID API.
for more description here
Registration ID expire and under the Instance ID lifecycle
your app or the Instance ID service may need to refresh tokens in the
event of a security issue or when a user uninstalls and reinstalls
your app during device restoration. Your app must implement a listener
to respond to token refresh requests from the Instance ID service.
here you can find a good explanation
EDIT
summarized:
there is no expiration time defined by GCM server
you tell the GCM server when the reg ID expires
if you do not tell the GCM Server about the expiration, it will not expire, even if the app was uninstalled on the respective device
google reserves the right to update the IDs, but there is no "rule", google may (but not necessarily does) update it at any time, but if so, you will be informed by receiving a canonical_id
Now we want to send some notification to users who have not login for a long time. But their push-tokens in our db may be expired.
What will happen if we send push notifications to too many invalid tokens?
Will google allow this without any limit?
GCM Registration IDs don't expire as far as I know. The Registration IDs you are referring to are not invalid (since they are not some random IDs you generated. You got them from the GCM server). In the worst case, you will get a NotRegistered error for some of them, which will let you know which Registration IDs you should delete.
You shouldn't have any problems sending messages to those Registration IDs.
When Sending Push notification, it can only be sent with 1000 parameters of token at a time.
Google does not know if the token are expired or not in the first instance.
irrespective of token being expired on not the same number of token is assumed to the sent
All token will hit the server first before being sent to client which their parameter are included
My app uses gcm. Each time user logs in, new gcm token is registered and sent to my 3rd party server. Each time user logs out, gcm token is unregistered. This woks without any problems.
The problem is that when it comes to testing, tester can uninstall the app without loging out, and then install it back again and log into another account. Then he'll recieve two gcms from two different account. This means he'll recieve private gcms for account hes not currently loged into. This can even happen with live users sometimes.
GCM documentation states that gcm tokens can expire sometimes if the application is uninstalled. In practice, this never happens.
http://developer.android.com/google/gcm/gcm.html
GCM documentation also states that you can unregister GCM tokens by executing
Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
startService(unregIntent);
But this method doesn't seem to work if you try it after reinstall. I do recieve callback which tells me that token is unregistered, but gcm token still works ok.
My question is: can you ensure that there are no valid gcm tokens for your application? I'd really like to unregister all existing tokens during application first start, or at least reset them from the phone settings.
GCM tokens for your app are unique for each device, so if you ever get a different user telling you they are using the same GCM token as some other user, then you know that the situation you described has occurred. Basically, every time you receive a GCM token, you should delete all older records that have that same GCM token before assigning it ONLY to the new user.
I believe you'll receive an error when your server send a message to the invalidated registration id. I think you can catch this error to delete these registrations id from your database/datastore.
Also from the doc (canonical id):
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.