Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send GCM notification to an offline device

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

like image 508
user1537779 Avatar asked Jun 04 '13 06:06

user1537779


People also ask

How does GCM push notification work?

The first step in GCM is that a third-party server (such as an email server) sends a request to Google's GCM server. This server then sends the message to your device, through that open connection. The Android system looks at the message to determine which app it's for, and starts that app.

What is FCM and GCM?

Firebase Cloud Messaging (FCM), formerly known as Google Cloud Messaging (GCM), is a cross-platform cloud solution for messages and notifications for Android, iOS, and web applications, which as of June 2022 can be used at no cost.

Is GCM reliable?

We evaluate GCM in real world experiments, and at a reasonable scale involving thousands of real users. Our findings reveal that the GCM message delivery is unpredictable, namely having a reliable connection to Google's GCM servers on the client device does not guarantee a timely message arrival.


2 Answers

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.

like image 65
Kunal S. Kushwah Avatar answered Oct 13 '22 07:10

Kunal S. Kushwah


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>
}
like image 45
JHH Avatar answered Oct 13 '22 08:10

JHH