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?
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:
- Have webservice function like registerDevice(GCM_ID,DeviceID)
- Now from DB fetch the GCMIdColumn where DeviceIDColumn = DeviceID. If this GCMIdColumn != GCM_ID, then update. Else do nothing.
- 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!
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.
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.
Most probably its sent multiple times from server side