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)
Related
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?
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.
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.
I need to send push notifications (PN) at some fixed time. For example, I don't want to wake my users before 8AM, so I would like to instruct google to deliver PNs at 9AM each day.
Problem is, my users might be spread all over the globe, I really cannot tell what locat time is there... does google give the ability to schedule PNs by local time of registered applications?
PS1: I read about iOS's UILocalNotification (maybe there is similar for Android too) but I don't want to set anything locally, I just want to send the PN from a remote server (with custom data) and put a restriction regarding the delivering time.
PS2: I am using Phonegap to develop the app and I am already able to send instant PNs to certain devices.
You can't instruct the push service (neither APNS nor GCM) when to deliver the notification. Both services try to deliver the notification as soon as possible (assuming the device is connected to the internet).
The only exception to my previous statement is that in GCM you can use the delay_while_idle flag to prevent the notification from being sent while the device is idle. This would prevent delivery while your users are not using the device.
If you want the notification to be delivered at a certain hour of day, and to consider the local time zone of the recipient device, you must manage it in your server. When your app sends the device token / registration ID to your server, you can send the local time zone of the device. Your server will know the time zone of each device, and send the notifications at the preferred hour.
I have successfully implemented the android push notification using google c2dm.
the problem is,when i push the message from the server i am getting success full deveice id. but the device some time receive push message,some time did not receive.(wifi is fully active)
i want the app to receive all the push message with out any push message lose,becoz each notification is important.
Is there any special parameter need to set or hw i would i confirm that device successfully received the message.
"C2DM makes no guarantees about delivery or the order of messages. So, for example, while you might use this feature to tell an instant messaging application that the user has new messages, you probably would not use it to pass the actual messages."
But you can try to play with 2 parameters:
collapse_key
An arbitrary string that is used to collapse a group of like messages when the device is offline, so that only the last message gets sent to the client. This is intended to avoid sending too many messages to the phone when it comes back online. Note that since there is no guarantee of the order in which messages get sent, the "last" message may not actually be the last message sent by the application server. Required.
delay_while_idle
If included, indicates that the message should not be sent immediately if the device is idle. The server will wait for the device to become active, and then only the last message for each collapse_key value will be sent. Optional.