Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate pushes received for a single device #17

Open
imaginator opened this issue Feb 11, 2015 · 1 comment
Open

Duplicate pushes received for a single device #17

imaginator opened this issue Feb 11, 2015 · 1 comment
Labels

Comments

@imaginator
Copy link
Member

I believe the "Buddycloud Pusher server" sending multiple push notifications for the same event. Either it's a post on channel or someone followed to my channel. The number of times it send the push notification to android client for any event based on the server side implementation.

And I guess the server save multiple registration ID's against the same android client. And it iterate all the registration ID's to send push notification which encounter client to receive sometimes 6 or sometimes 8 push notifications.

Please see the logs below (For more details on this issue - http://stackoverflow.com/questions/24963249/android-gcm-message-repeated-several-times-wakelockid-changes)
02-05 14:58:23.952: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=deminemtest@buddycloud.org, CONTENT=test, android.support.content.wakelockid=1, collapse_key=do_not_collapse}]

02-05 15:00:20.612: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=buddycloud234@buddycloud.org, CONTENT=test, android.support.content.wakelockid=2, collapse_key=do_not_collapse}]

02-05 15:01:17.097: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=deminem@buddycloud.org, CONTENT=test, android.support.content.wakelockid=3, collapse_key=do_not_collapse}]

02-05 15:02:00.807: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=deminem@buddycloud.org, CONTENT=test, android.support.content.wakelockid=4, collapse_key=do_not_collapse}]

02-05 15:02:40.357: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=deminem@buddycloud.org, CONTENT=test, android.support.content.wakelockid=5, collapse_key=do_not_collapse}]

02-05 15:03:10.977: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=deminem@buddycloud.org, CONTENT=test, android.support.content.wakelockid=6, collapse_key=do_not_collapse}]

02-05 15:03:34.342: D/com.buddycloud.GCMIntentService(5422): GCM: Message Received: Bundle[{CHANNEL_JID=lounge@topics.buddycloud.org, AUTHOR_JID=adnan@buddycloud.org, from=732635301617, event=POST_ON_SUBSCRIBED_CHANNEL, FOLLOWER_JID=deminem@buddycloud.org, CONTENT=test, android.support.content.wakelockid=7, collapse_key=do_not_collapse}]

This issue can also be one of the main reason for reported issue. - buddycloud/buddycloud-android#146

I have tested with my internal Push notification server and client code for handling push notification works perfectly fine. I receive only one push notification with Google cloud messaging service.

02-05 15:11:49.707: D/com.buddycloud.GCMIntentService(6954): GCM: Message Received: Bundle[{from=732635301617, message={"u":"14","t":"hello!","m":"12"}, android.support.content.wakelockid=1, collapse_key=do_not_collapse}]

Please discuss with me, if you need more information to fix this issue on server.
Best Regards,

Based on this database dump, I believe multiple GCM registration ID's are maintained against user JID. And UserPostedMentionQueryHandler.java or different handlers try to iterate all the registration ID's against this JID for sending push notifications.

There are two different solutions to solve this problem:

a) If the design approach was intended to maintain the notification settings for user JID across all different platforms (android, iOS, desktop and etc.). Then we need to introduce new attribute in the schema 'platform' or 'platformType' and handle the uniqueness.

b) Server should always maintain single GCM registration ID against user JID.

Note: GCM registration ID unique to per application and per device. Re-Installing/Uninstalling almost always create new registration ID. Application updates may result in new registration ID being issued.

Taken from: http://developer.android.com/google/gcm/gcm.html

An ID issued by the GCM servers to the Android application that allows it to receive messages. Once the Android application has the registration ID, it sends it to the 3rd-party application server, which uses it to identify each device that has registered to receive messages for a given Android application. In other words, a registration ID is tied to a particular Android application running on a particular device. Note that registration IDs must be kept secret.

Note: If you use backup and restore, you should explicitly avoid backing up registration IDs. When you back up a device, apps back up shared prefs indiscriminately. If you don't explicitly exclude the GCM registration ID, it could get reused on a new device, which would cause delivery errors.

Some of the useful links for how to maintain the unique GCM registration ID on server.

http://stackoverflow.com/questions/11504808/gcm-apns-how-are-registration-ids-generated
http://stackoverflow.com/questions/19252214/how-to-store-uniquely-a-gcm-registration-id-into-mysql

@abmargb said:

As you can see in the database dump, the field 'type' does the job of the 'platformType' you are suggesting. However, it is actually expected that you have multiple registration IDs of the same type (e.g. GCM) in the database in cases you have more than one Android device running Buddycloud.

Thus, it is up to the Android client to make sure that no duplicates are registered in the Pusher for the same device by removing old registration IDs. We can't guarantee it the server side.

@Deminem said

Thanks for your feedback. Great to know that the current design model maintain platformType.

Android client only guarantee to un-register from GCM and buddycloud pusher service (if and only if) logout/explicit action perform.

In the case of Un-installing the app, it's impossible for android client to remove the dangling registration ID reference from both GCM and buddycloud pusher server. Although the android client also try to remove old registration ID on re-install action, but the app sandbox doesn't have a track of old dangling registration ID reference (because app sandBox always get deleted on un-install).

In order to provide the support for user having multiple Android device running Buddycloud, you need to create a composite-key.
For example <device UDID + GCM Registration ID> or <Server Random ID + GCM Registration ID> to handle this scenario. And always replace the registration ID for user w.r.t device UDID on android client new registration.

Otherwise, server will always be having the dangling registration ID references in the database and GCM try to send push notification for those ids.

Please let me know your thoughts on this approach.

@Deminem said:

Actually, the composite key would be user + device UDID to keep track of GCM registration ID's for each android client. Sorry for the typo mistake.

To rephrase more properly, please find the attached file for your consideration. Please let me know, if something is wrong in this design approach.

@abmargb said

to make things simpler, wouldn't it be better if the pusher trashed registration IDs that are no longer valid? That way we wouldn't need to store device IDs. Also, AFAIK, it is not recommended that we handle device ID as unique identifiers.

@Deminem said:

That would be wonderful, if you able to purge/trash the invalid registration IDs. The main idea behind this issue to maintain "latest unique" registration ID for each android/iOS device. Can you please let me know, how would you trigger the purging service (on what criteria) ?

After some more investigation on this issue, I believe Google already handle this issue through Canonical IDs. Please see these useful links here.

http://stackoverflow.com/questions/23241324/how-to-resolve-android-gcm-notifications-duplicate-messages
http://developer.android.com/google/gcm/adv.html

Actually, the composite key would be user + device UDID to keep track of GCM registration ID's for each android client. Sorry for the typo mistake.

Android client only guarantee to un-register from GCM and buddycloud pusher service (if and only if) logout/explicit action perform.

In the case of Un-installing the app, it's impossible for android client to remove the dangling registration ID reference from both GCM and buddycloud pusher server. Although the android client also try to remove old registration ID on re-install action, but the app sandbox doesn't have a track of old dangling registration ID reference (because app sandBox always get deleted on un-install).

In order to provide the support for user having multiple Android device running Buddycloud, you need to create a composite-key.
For example <device UDID + GCM Registration ID> or <Server Random ID + GCM Registration ID> to handle this scenario. And always replace the registration ID for user w.r.t device UDID on android client new registration.

Otherwise, server will always be having the dangling registration ID references in the database and GCM try to send push notification for those ids.

Please let me know your thoughts on this approach.

@abmargb said:

As you can see in the database dump, the field 'type' does the job of the 'platformType' you are suggesting. However, it is actually expected that you have multiple registration IDs of the same type (e.g. GCM) in the database in cases you have more than one Android device running Buddycloud.

Thus, it is up to the Android client to make sure that no duplicates are registered in the Pusher for the same device by removing old registration IDs. We can't guarantee it the server side.

gcm notification proposal

@imaginator imaginator added the bug label Feb 11, 2015
@imaginator
Copy link
Member Author

@abmargb said:
to make things simpler, wouldn't it be better if the pusher trashed registration IDs that are no longer valid? That way we wouldn't need to store device IDs. Also, AFAIK, it is not recommended that we handle device ID as unique identifiers.

@Deminem said:

That would be wonderful, if you able to purge/trash the invalid registration IDs. The main idea behind this issue to maintain "latest unique" registration ID for each android/iOS device. Can you please let me know, how would you trigger the purging service (on what criteria) ?

After some more investigation on this issue, I believe Google already handle this issue through Canonical IDs. Please see these useful links here.

http://stackoverflow.com/questions/23241324/how-to-resolve-android-gcm-notifications-duplicate-messages
http://developer.android.com/google/gcm/adv.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant