15

I have a list of GCM registered users and their corresponding registration Ids in a database table, and I actually want to unregister a user whenever he/she is deleted from the table. I found a lot of examples here in Stackoverflow, but most of them are based on the old GCMRegistrar API which is now deprecated. I'm using GoogleCloudMessaging API and registering a user by following method:

private void registerUser(){
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(getBaseContext());
        String regId = "";
        try {
            regId = gcm.register(getString(R.string.project_number));
            Log.i("registrationId", regId);
        } 
        catch (IOException e) {
            Log.i("Registration Error", e.getMessage());
        }
}

I have an administrator app, which acts as a 3rd-party application server, since it pushes notifications to all users. I want to unregister a specific user from this administrator app with following method:

private void unRegister(String regId) {

        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(getBaseContext());
        try {
            gcm.unregister();
        } 
        catch (IOException e) {     
        System.out.println("Error Message: " + e.getMessage());
        }

   }

But it confuses me that unregister() method does not take registration Id as an argument, which makes it impossible to unregister a specific device. Is there any way to unregister a specific device from GCM by registration Id ?.

Osman Esen
  • 1,704
  • 2
  • 21
  • 46
  • 1
    lol, but you run this code **on specific device** so it unregister this specific device ... – Selvin Jan 21 '15 at 00:03
  • I'm running the "register" method on the specific user device, but I have to unregister the user from the administrator device. – Osman Esen Jan 21 '15 at 00:04
  • 1
    administrator device? there is no such thing in GCM – Selvin Jan 21 '15 at 00:05
  • I mean the 3rd party application server, which sends notification to all registered devices. I have implemented the server in an android application. – Osman Esen Jan 21 '15 at 00:06
  • Benefiting from Amazon-SNS service – Osman Esen Jan 21 '15 at 00:08
  • after register save regID in SharedPreferences then send it to 3p server for registration... if user click unregister then: send the regid to 3p server to unregister then do gcm unregister ... – Selvin Jan 21 '15 at 00:08
  • "send the regid to 3p server to unregister then do gcm unregister" --> how do I implement this part programatically ?. It confuses me that the unregister method does not accept any regId as arguments ?. – Osman Esen Jan 21 '15 at 00:11
  • when an app is uninstalled how to send my server a request to remove the id from my database tables as when an app is uninstalled i cannot perform action. – Sudhanshu Gaur Sep 09 '15 at 17:13

2 Answers2

21

This method does the trick:

gcm.unregister();

However, gcm.unregister() is now deprecated, hence, you must use one of these:

InstanceID.deleteToken() or InstanceID.deleteInstanceID().

These methods take the following parameters:

public void deleteToken (String authorizedEntity, String scope)

Being authorized entity the entity that you want to remove...

// THE FOLLOWING EXPLANATION IS ONLY FOR "UNREGISTER"

So, based on your comment:

But it confuses me that unregister() method does not take registration Id as an argument, which makes it impossible to unregister a specific device.

That's because you are expecting it to work in a way that it doesn't. It seems like you want to be able to make an http request passing a parameter to uregister(e.g. "http://www.gcmserver.com?unregisterid=xxxx"), and that's not the way it works, this is the way it works based on Google's Documentation:

How unregistration works

An application can be automatically unregistered after it is uninstalled from the device. However, this process does not happens right away, as Android does not provide an uninstall callback. What happens in this scenario is as follows:

The end user uninstalls the application.

The 3rd-party server sends a message to GCM server.

The GCM server sends the message to the device.

The GCM client receives the message and queries Package Manager about whether there are broadcast receivers configured to receive it, which returns false.

The GCM client informs the GCM server that the application was uninstalled.

The GCM server marks the registration ID for deletion.

The 3rd-party server sends a message to GCM.

The GCM returns a NotRegistered error message to the 3rd-party server.

The 3rd-party deletes the registration ID.

So, based on that, what the method gcm.unregister() actually does is marking that device for deletion(think of it as forcing the first steps of the process without actually uninstalling the app), letting the server know that it no longer needs to get notifications, also by not taking an "Id" as a parameter it means that it is referencing to that specific device.

Regards!

Martin Cazares
  • 13,637
  • 10
  • 47
  • 54
  • how much time does GCM need to unregister ID? I tried to uninstall the app and sent message over GCM. Then, i installed the app but i could send message using old gcm ID. Another question; What if user reinstall the app? In this case, device recives a message twice. Because, during reinstalling the app, if GCM doesn't try to send message, it will not notice that app uninstalled. Can i handle this cases, if i always call gcm.unregister(), before register the device to GCM? – Eren Dec 24 '15 at 07:57
  • 1
    What if I want to unregister from GCM when the user logs out of the application? Should a new IntentService be created in order to unregister ? – JGPhilip Sep 27 '16 at 10:48
4

unregister() is now deprecated:

https://developers.google.com/android/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#unregister()

Quoting the docs you should call:

Instead use InstanceID.deleteToken() or InstanceID.deleteInstanceID().
Felipe Duarte
  • 1,079
  • 14
  • 20