Do Gcm Registration Id's Expire

Do GCM registration id's expire?

EDIT: THIS ANSWER IS WAY OUT OF DATE, I HAVE NO IDEA WHAT THE CURRENT BEHAVIOR IS


I found the answer myself. You don't explicitly need to re-register all the time, just once according to the example in the docs.

Also, unlike previous versions of GCM and C2DM, Google itself does not refresh the registration itself now: once you have the registration id from the initial registration you are good to go, except for one case: you do still need to re-register when the user upgrades to a new version (this case is also handled in the example in the link above):

When an application is updated, it should invalidate its existing
registration ID, as it is not guaranteed to work with the new version.
Because there is no lifecycle method called when the application is
updated, the best way to achieve this validation is by storing the
current application version when a registration ID is stored.

Google Cloud Messaging registration id expiration

I am trying to understand when the registration id expires

GCM server usually refreshes(So your old registration id is expired) the registration ids. When exactly this happens is not documented anywhere. But you will be notified when this happens.

How are we notified?

When you send a notification to a registration id which is expired,
for the 1st time the message(notification) will be delivered but you
will get a new registration id with the name canonical id. Which mean,
the registration id you sent the message to has been changed to this
canonical id, so change it on your server side as well
.


If Google decides to refresh the ID and my server is till sending the
message to the old ID I dont think the message will get sent

Like I said, it will be sent for the 1st time, even after expiry.


Also the same post says that the id would get refreshed when the app
version changes

I don't think this happens for sure. But even if it happens(registration id changes) its the same scenario as explained above, so all you need is to take care of the canonical id.

EDIT

$result = curl_exec($ch);
$result = json_decode($result);
$canonical_ids_count = $result->canonical_ids;
if($canonical_ids_count){
//update your DB by replacing the registration id with
//the canonical id(new registration id)
}

does GCM delete the old registration id if user installs app again immediately after uninstall?

From the official documentation:

How uninstalled client app unregistration works

A client app can be automatically unregistered after it is
uninstalled. However, this process does not happen immediately.
What
happens in this scenario is:

  1. The end user uninstalls the client app.
  2. The app server sends a message to GCM connection server.
  3. The GCM connection server sends the message to the GCM client on the device.
  4. The GCM client on the device receives the message and detects that the client app has been uninstalled; the detection details depend on the platform on which the client app is running.
  5. The GCM client on the device informs the GCM connection
    server that the client app was uninstalled.
  6. The GCM connection server
    marks the registration token for deletion.
  7. The app server sends a
    message to GCM.
  8. The GCM returns a NotRegistered error message to the
    app server.
  9. The app server should delete the registration token.

Note
that it might take a while for the registration token to be completely
removed from GCM. Thus it is possible that messages sent during step 7
above get a valid message ID as a response, even though the message
will not be delivered to the client app.
Eventually, the registration
token will be removed and the server will get a NotRegistered error,
without any further action being required from the app server.

However, it can apparently happen that you still get the notification for the old registration ID, as users state in other questions:

  • App receives duplicate notification using GCM after reinstalling
  • Android GCM and multiple tokens
  • https://stackoverflow.com/questions/27845298/gcm-deleting-app-and-reinstalling-multiple-notifications
  • Unregistering and re-registering for GCM messages causes two regId's to be valid. Is this as intended?
  • Do old GCM tokens live on even after an uninstall?

For this problem, there is a functionality called "canonical IDs":

Canonical IDs

If a bug in the client app triggers multiple registrations for the
same device, it can be hard to reconcile state and the client app
might end up with duplicate messages.

Implementing canonical IDs can help you more easily recover from these
situations. 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.

GCM 3.0: New registration does not expire tokens registered with GCMRegistrar

I have finally received an answer from Google support regarding my issue. It turned out that this was intended behavior:

What you observed is in the intended behavior due to the need to support backward compatible
registration ID.

We recommend you to flag the old registration ID from gcmregistrar() and don't use that to send anymore once you have the registration token from getToken(). (I believe you probably has implemented a solution to detect such)

Our solution was to simply remove old registration tokens from our push server before registering new user.

We did not use GCMRegistrar.unregister() as we observed that it was able to unregister new tokens (obtained via getToken()).

UPDATE:

I just wanted to provide a quick update to anyone interested in this subject.

It seems that this issue was fixed as when we tested our registration mechanism recently, it turned out that new GCM tokens replace (and unregister) old tokens.

In GoogleCloudMessaging API, how to handle the renewal or expiration of registration ID?

I am giving a way as What I implemented in my application

@Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
//displayMessage(context, getString(R.string.gcm_registered));
//ServerUtilities.register(context, registrationId);
//1. Store this id to application Prefs on each request of device registration
//2. Clear this id from app prefs on each request of device un-registration
//3. Now add an if check for new registartion id to server, you can write a method on server side to check if this reg-id matching for this device or not (and you need an unique identification of device to be stored on server)
//4. That method will clear that if id is matching it meanse this is existing reg-id, and if not matching this is updated reg-id.
//5. If this is updated reg-id, update on server and update into application prefs.
}

You can do like this also

if reg_id exists_into prefrences then
if stored_id equals_to new_reg_id then
do nothing
else
say server to reg_id updated
update prefrences with new id
end if
else
update this id to application prefs
say server that your device is registered
end if

But problem arises when, user clears the application data and you will loose the current reg-id.


Update for new API example Credits goes to Eran and His Answer Handling registration ID changes in Google Cloud Messaging on Android

Google changed their Demo App to use the new interface. They refresh the registration ID by setting an expiration date on the value persisted locally by the app. When the app starts, they load their locally stored registration id. If it is "expired" (which in the demo means it was received from GCM over 7 days ago), they call gcm.register(senderID) again.

This doesn't handle the hypothetical scenario in which a registration ID is refreshed by Google for an app that hasn't been launched for a long time. In that case, the app won't be aware of the change, and neither will the 3rd party server.

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);
mDisplay = (TextView) findViewById(R.id.display);

context = getApplicationContext();
regid = getRegistrationId(context);

if (regid.length() == 0) {
registerBackground();
}
gcm = GoogleCloudMessaging.getInstance(this);
}

/**
* Gets the current registration id for application on GCM service.
* <p>
* If result is empty, the registration has failed.
*
* @return registration id, or empty string if the registration is not
* complete.
*/
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) {
Log.v(TAG, "Registration not found.");
return "";
}
// check if app was updated; if so, it must clear registration id to
// avoid a race condition if GCM sends a message
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion || isRegistrationExpired()) {
Log.v(TAG, "App version changed or registration expired.");
return "";
}
return registrationId;
}

/**
* Checks if the registration has expired.
*
* <p>To avoid the scenario where the device sends the registration to the
* server but the server loses it, the app developer may choose to re-register
* after REGISTRATION_EXPIRY_TIME_MS.
*
* @return true if the registration has expired.
*/
private boolean isRegistrationExpired() {
final SharedPreferences prefs = getGCMPreferences(context);
// checks if the information is not stale
long expirationTime =
prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
return System.currentTimeMillis() > expirationTime;
}


Related Topics



Leave a reply



Submit