Dealing with stored messages in GCM after registration id change - android

The case here is of using GCM for payload based push notifications. Let's say about 10 odd push notifications are sent to the GCM server in a non-collapsible way so that all of them are queued. The user hasn't got those notifications yet because the user hasn't connected to internet.
If after connecting to internet the user updates the application before receiving those notifications, the registration id for the app is going to change.
Wanted to know, if in this case, would the stored notifications still get delivered to the device or would they be discarded altogether?
I was unable to locate the handling of stored notifications when registration id changes anywhere in the documentation. Could anyone please shed some light over this?
Thank you very much.

I've seen no documentation about this very unlikely scenario either.
The reason it's so unlikely is that once you connect to the internet (in order to udpate the application), it is very likely you'll get the stored messages before you download and install the update.
Now, suppose that you didn't get them before installing the update. When the application is being updated, there's a chance that due to an old bug in GCM, the app will get unregistered automatically if it receives a message while getting upgraded. That's precisely the reason why the GCM docs suggest to re-register to GCM each time the app is updated.
In the unlikely event that this bug happens, you will lose all the undelivered messages stored for your device in GCM server, since your app will become unregistered on this device.
If, on the other hand, the undelivered messages are delayed in the GCM server until after you updated the app, launchd the updated app and re-registered to GCM, it's likely that the stored messages will be delivered, even if the re-registration results in a new registration ID (note that the registration ID won't necessarily change), since old registration IDs continue to work even after a new registration ID is assigned.
All of that being said, you should never rely on all the GCM messages always being delivered. It is never guaranteed. Whenever a user starts your app, you should synchronize it with your server (load whatever data is relevant), and therefore any GCM messages that were not delivered will become irrelevant.

Related

How to send FCM notification to rarely used app

I have a Cordova app that receives secure messages from a service provider, through our servers, to an app installed on a phone by the user. However, the app may be rarely used (in the order of 12 months or so). In the event that the provider needs to contact the user we currently send an FCM notification. The problem is that because we don't want to place any drain on the user's battery for a service that they rarely use (although is extremely valuable) then we don't try and run anything in the background - which means that according to the firebase document Lifetime of a message the message will be discarded if the user doesn't open the app for one month.
The referenced doc states:
If the device has not connected to FCM for more than one month, FCM still accepts the message but immediately discards it. If the device connects within four weeks of the last data message you sent to it, your client receives the onDeletedMessages() callback. The app can then handle the situation properly, typically by requesting a full sync from the app server.
How are we supposed to inform the user that there is a message for them?
I understand why such a precaution can make sense, but what options exist to allow us to receive the notification causing minimal impact on the users' device?

Receive all the push notifications when devices are offline

I'm creating an iOS and Android native app, using Firebase for sending push notifications.
It's working fine, but when I switch off my devices and send some notifications, after starting the devices, I just receive the last one sent for iOS, and the same for Android.
Is there a way to receive all the push notifications even when the devices are offline and they're started?
Referencing a couple of references:
iOS:
Apple Push Notification service includes a Quality of Service (QoS)
component that performs a store-and-forward function. If APNs attempts
to deliver a notification and the destination device is offline, APNs
stores the notification for a limited period of time and delivers it
when the device becomes available again. This component stores only
the most recent notification per device and per app. If a device is
offline, sending a notification request targeting that device causes
the previous request to be discarded. If a device remains offline for
a long time, all its stored notifications in APNs are discarded.
This component stores only the most recent notification per device and per app.
If a device is offline, sending a notification request targeting that device causes the previous request to be discarded.
This would mean that only one notification is preserved and that sending a new one replaced the old one. So I don't think it's possible.
Local and Remote Notification Programming Guide
Android:
On Android and Web/JavaScript, you can specify the maximum lifespan of
a message. The value must be a duration from 0 to 2,419,200 seconds
(28 days), and it corresponds to the maximum period of time for which
FCM stores and attempts to deliver the message. Requests that don't
contain this field default to the maximum period of four weeks.
and
Currently, time_to_live is not supported for notification messages on iOS
and
If the device is not connected to GCM, the message will be stored
until a connection is established (again respecting the collapse key
rules). When a connection is established, GCM delivers all pending
messages to the device. If the device never gets connected again (for
instance, if it was factory reset), the message will eventually time
out and be discarded from GCM storage. The default timeout is 4 weeks,
unless the time_to_live flag is set.
and
Finally, when GCM attempts to deliver a message to the device and the
application was uninstalled, GCM will discard that message right away
and invalidate the registration token. Future attempts to send a
message to that device will result in a NotRegistered error.
When a connection is established, GCM delivers all pending messages to the device.
If the device never gets connected again (for instance, if it was factory reset), the message will eventually time out and be discarded from GCM storage.
The default timeout is 4 weeks, unless the time_to_live flag is set.
Finally, when GCM attempts to deliver a message to the device and the application was uninstalled, GCM will discard that message right away and invalidate the registration token.
Meaning it should be receiving the pending messages. Unless the device is factory reset or uninstalled.
About FCM Messages
Messaging Concepts and Options (although this is deprecated and now suggests to reference FCM messaging, linked above)

GCM Pushnotification not received, though GCM server reported as sent successfully

So, I am sending push notification to thousands of my users. I have noticed that GCM server respond back with "messageId" and according to the documentation it is successfully sent to the user, but the user (one of our internal device) did not receive the notification. And this happens very randomly, same device receives the notification sometimes. Is this normal? if not what could be the possible reason behind this and what would be the fix?
Thanks
Riz
Though not a complete list, the issue could be any of the following:
The affected phones were not online/connected at the time of the message being sent.
Your setup uses a collapse key, which would collapse prior messages being sent under the same collapse key (thus the reason your device only receives some notifications and not all).
The affected phones were asleep/locked, and you did not implement a Wakeful Broadcast Receiver in your client app.

GCM push message with high frequency

I am planning to implement Android push notification serivce for an app that might require receiveing even two messages per device per second. I would like to know if GCM Push messaging is the way to go or should I stick to SyncAdapter or some other technology? Single device will receive up to few thousand notifications per day. Message size will be very small to 4kb limit is fine.
If it is critical that all of the messages reach the device and none are lost, GCM alone is not the right choice, since in case GCM server would temporarily lose connection with a device, there's a limit to the number of messages that would be stored for later delivery for that device in the GCM server.
Therefore, if you have to update your app that frequently, you should probably keep an open connection between your server and your app, and load data from the server periodically.
Though the GCM server limits the number of messages that will be stored for later delivery in the case of a device disconnect, you can always create a collapse_key.
According to GCM documentation, if there is already a message with the same collapse key (and registration ID) stored and waiting for delivery, the old message will be discarded and the new message will take its place (that is, the old message will be collapsed by the new one).
Essentially, if you only need the most recent push notifications rather than all prior sent, GCM is acceptable for sending push notifications with high frequency.
You can read more about this in the GCM Advanced Topics.

How to use GCM notification sync

I know that in never version of GCM you can dismiss notifications based on userId and not device id. This essentially syncs this action with all devices that user is using with same google account. Documentation page for this can be found here and it is quite helpful
http://developer.android.com/google/gcm/notifications.html
Only thing I don't understand from there is:
Do I need to write code in my app to contact the GCM sever or my own server to trigger dismissal on other devices or does this happen automatically when notification is dismissed or opened ?
This is the part that led me to think that you need to do it manually but I am not certain :
"You should design your app to handle cases where the app receives a dismissal message, but has not yet displayed the notification that is being dismissed."
Yes, you have to write code in your app to trigger the dismissal message, as well as handle it.
Note: A notification dismissal message is like any other upstream message, meaning that it will be delivered to the other devices that belong to the specified notification_key. You should design your app to handle cases where the app receives a dismissal message, but has not yet displayed the notification that is being dismissed. You can solve this by caching the dismissal and then reconciling it with the corresponding notification.
This makes sense, because GCM doesn't know how your app handles an arriving GCM message. Your app might display a notification (which needs to be dismissed if it was already handled on another device belonging to the same user), or it might perform some background sync with the server (in which case no dismissal message needs to be sent).
The point of this new feature is that you send a single message to a single notification key instead of sending it to multiple registration IDs, and an app installed on any of the devices belonging to the same user doesn't need to know the registration IDs of all those devices. It only needs to know the notification_key in order to communicate with the other devices.
i think its your serer that need to be contacted
this keeps the flow consistence and also , when contacting GCM server to send message you need to provide your API-key and project Id ... and this is critical to be stored on the mobile application.
thats why you should contact your server, in his turn, your server will contact GCM server
this is my opinion.

Categories

Resources