Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCM registering with two different working registration ids

I'm having a slight issue with device registration management on my client/server for push notifications.

Problem

The problem that I'm having is that when I uninstall the application and re install it the application returns an empty string for the registration id (GCMRegistrar.getRegistrationId(this)) which I re-register the device with my server. The problem is that I get a new, different registration id (sometimes) and BOTH WORK! So I don't know how server side to know whether it's for the same device. I should also note I'm not changing the application version. Do any changes to the manifest trigger a new registration id to be issued?

On the Android side, I do the following:

    /**
     * Registers this android device with GCM
     */
    private void registerDeviceWithGCM() {
        GCMRegistrar.checkDevice(this);
        GCMRegistrar.checkManifest(this);
        String regId = GCMRegistrar.getRegistrationId(this);
        if (regId.equals("")) {
            log.debug("Registering application with GCM");
            GCMRegistrar.register(this, ApplicationData.SENDER_ID);
        } else {
            log.debug("Already registered: " + regId);
            deviceRegistrationService.updateServerRegistrationData(this, regId);
        }
    }

In my GCMIntentService.java I do the following:

    /**
     * Triggered upon new device registration and updates registration info with the server
     *
     * @param context context received from
     * @param regId   device's registration id
     */
    @Override
    protected void onRegistered(Context context, String regId) {
        Log.d(TAG, "Registering: " + regId);
        Intent intent = new Intent(RegistrationReceiver.REGISTRATION_INTENT);
        intent.putExtra(RegistrationReceiver.REGISTRATION_ID, regId);
        context.sendBroadcast(intent);
    }

In my RegistrationReceiver.java I have the following:

    /**
     * Triggers the device registration with cirrus
     *
     * @param context unused
     * @param intent  used to get registration id
     */
    @Override
    public void handleReceive(Context context, Intent intent) {
        log.debug("Received registration with intent action: " + intent.getAction());
        if (intent.getAction().equals(REGISTRATION_INTENT)) {
            String regId = intent.getStringExtra(REGISTRATION_ID);
            log.debug("Received registration intent with registration id: " + regId);
            deviceRegistrationService.updateServerRegistrationData(loginActivity, regId);
        } else if (intent.getAction().equals(REGISTRATION_FAILED_INTENT)) {
            log.debug("Received registration failed intent, displaying error message");
            showRegistrationFailedMessage(intent);
        }
    }

Again, the problem here is that I have two ore more registration id's that all work (it wouldn't be a problem if I the old one simply didn't work when trying to post a message from the server as I can simply clean that up).

like image 953
vincentjames501 Avatar asked Apr 09 '13 17:04

vincentjames501


People also ask

What is GCM registration ID?

A Registration ID is an identifier assigned by GCM to a single instance of a single application installed on an Android device. The device is assigned this identifier when it registers to Google Cloud Messaging. The GCM documentation doesn't specify what information is encoded in this identifier.


1 Answers

Sometimes Google changes the registration ID and you'll have multiple IDs associated. The server that sends the notification (your server) has to update the database with the new ID.

For more info check this document:

http://developer.android.com/google/gcm/adv.html

That says:

On the server side, as long as the application is behaving well, everything should work normally. However, if a bug in the application triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages.

GCM provides a facility called "canonical registration IDs" to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your application. This is the ID that the server should use when sending messages to the device.

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.

like image 148
nunofmendes Avatar answered Nov 08 '22 06:11

nunofmendes