Send GCM notification to an offline device - android

If I am sending a notification to a device, and that device is offline I get something like:
Error: Unavailable
And I have to resend.
My question is:
Will the GCM server keep these notifications in a queue and automatically resend when the device is online? Or it must be completely handled by me.
Because if the GCM server is going to send them automatically(once the device is online), until it actually sends the notifications, my server assumes they are already sent. How to track the time when the notifications are resent successfully?
I might mark on my server side that the notifications are not sent by looking at the Unavailable error message but cannot make out how to mark them as sent once the GCM successfully sends the notifications.
Thank You

A/c to documentation--- When a 3rd-party server posts a message to GCM and receives a message ID back, it does not mean that the message was already delivered to the device. Rather, it means that it was accepted for delivery. What happens to the message after it is accepted depends on many factors.
If the device is connected but idle, the message will still be delivered right away unless the delay_while_idle flag is set to true. Otherwise, it will be stored in the GCM servers until the device is awake. And that's where the collapse_key flag plays a role: 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). However, if the collapse key is not set, both the new and old messages are stored for future delivery.
Note: There is a limit on how many messages can be stored without collapsing. That limit is currently 100. If the limit is reached, all stored messages are discarded.

What I did was to separate the push indication from the payload. In my GCM message I only include a URI to the payload, and I store the payload in a database table accessible through the URI in the message.
When the client receives a message, it could e.g. look like this, with HATEOAS style links:
{
_links: {
message: {
rel: 'message',
href: 'https://my-server.com/push/<messageId>'
}
}
}
The client then goes to GET the message payload from the URI, at which point the server knows that it's been delivered and can update accordingly. Fetching the payload also deletes it.
If GCM re-delivery is not robust enough this also means that the client can choose to manually fetch all pending messages, e.g. when network connectivity is resumed after being offline, by having an endpoint that returns all messages for a given ANDROID_ID or similar. If then later the GCM message is delivered, the client would get a 404 for the URI in that message and treat that as a no-op, i.e., message already handled.
If this is overkill, a light-weight approach to just achieve server awareness of message delivery is to have an endpoint that simply ACKs the reception of a message with a given ID, such as
POST https://my-server.com/push/notifyReceived
{
messageId: <messageId>
}

Related

Does FCM resend notifications within a lifetime to new android users?

I use Firebase for sending notifications to an app users with 4 weeks lifetime. I guess no, but if a new user installs the app, will he recive the alive notifications?
FCM sends the message as soon as feasible. The default time_to_live is four weeks, which works in a way that only if the message is that is sent to the corresponding recipients at the time the message was sent, it would only be kept on queue by the FCM servers until such time that they come online.
With your use-case, I'm presuming that this is for Topics Messaging, in which case at the time that the message was technically sent, new subscribers will not receive it.
I understand the time_to_live parameter will affect the delivery of the messages.
This means that the recipient already exists but for some reason the message can't be delivered, and the parameter will be used to set a maximum time of delivery after which FCM will just not go ahead with completing the task.
New users wouldn't qualify as recipients at the time of the message being sent.
FCM documentation

Dealing with stored messages in GCM after registration id change

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.

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 receive multi c2dm notifications?

I'm using C2DM to send notification for my android App and it is working fine. But i am able to get only one notification at a time. so that while receiving the notification, it replaces previously received notification.
So how to receive multiple C2DM notification, like receiving normal SMS?
Give the messages different collapse_keys. Here's an excerpt from the official docs:
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.
On a side note; you are not supposed to use the push messages too frequently:
Are you sending C2DM messages too frequently? If you need to
communicate with your application frequently over a short period of
time, C2DM is probably not the best solution. Instead, consider
implemeting XMPP or your own protocol to exchange messages, and use
C2DM only to send the initial notification.

android push notification c2dm

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.

Categories

Resources