GCM - multiple notifications

2019-08-31 15:08发布

问题:

I am using Google Cloud Messaging (one way only, i.e. server to client) to receive Push-notifications. I am receiving these, and at first everything was fine, but now, after a bit over a week, I get multiple notifications; 3 on one device, and 7 on the other.

My theory is that the devices register with different ids, and thus get multiple notifications.

But why can that be? I am using Googles sample Android project, adapted it to mine, but can't see what would cause these multiple registrations. Is it because the registration ids have expired?

EDIT: All registrationIds on the sever are different however.

EDIT2: I think I called GCMRegistrar(context) in the onDestroy()-method of the activity, but didn't actually unregister the registration id on my server. Might that be the problem? What does it mean if the registration id is unregistered?

回答1:

After reflecting on your latest comment (The GCM engine might change the registration ID whenever it determines it need to, and this might happen at anytime without prior warning, that's why you should always check if the last registration ID matches the one that is current), I have this solution:

  1. Have webservice function like registerDevice(GCM_ID,DeviceID)
  2. Now from DB fetch the GCMIdColumn where DeviceIDColumn = DeviceID. If this GCMIdColumn != GCM_ID, then update. Else do nothing.
  3. If there is no row with having DeviceIDColumn = DeviceID, then insert (GCM_ID,DeviceID).

DeviceID: A ID picked up from the App. GCM_ID: Id returned by GCM.

Now the only thing you must be certain about is that DeviceID you generate from the app should be unique. You can combine 2 or more properties of the device's configuration to make it unique.

Generate Device ID

public String getDeviceID(Context context) {
        TelephonyManager TelephonyMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        String szImei = TelephonyMgr.getDeviceId(); // Requires READ_PHONE_STATE
        String m_szDevIDShort = "35" + //we make this look like a valid IMEI
                Build.BOARD.length()%10+ Build.BRAND.length()%10 +
                Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
                Build.DISPLAY.length()%10 + Build.HOST.length()%10 +
                Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
                Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
                Build.TAGS.length()%10 + Build.TYPE.length()%10 +
                Build.USER.length()%10 ; //13 digits
        if(Utills.debug)
            Log.i("getDeviceID",szImei+"==XXX=="+m_szDevIDShort);
        return szImei+"==XXX=="+m_szDevIDShort;
    }

Hope this is the solution you are looking for!



回答2:

Even without having seen your code, I guess the problem is the following:

The server is not checking whether a registered device is already registered in the database and thus you're having duplicated entries, therefore you're sending the same notification several times to the same client.

Even doing this, you need to implement a timeout policy. In my projects, I have a Thread that every X time sends a dummy HTTP request to the third-party server, so if a device fails to send it after a reasonable amount of time, it's a timeout and I remove it from the database.

I guess solving these 2 issues will solve your problem.



回答3:

This isn't a direct solution/fix to your answer but GCMRegistrar(context) have been deprecated for a while now. I would stay away from it as it is not recommended to use.

package com.google.android.gcm DEPRECATED — please use the GoogleCloudMessaging API instead of this client helper library — see GCM Client for more information.



回答4:

Most probably its sent multiple times from server side