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.
Related
I am currently trying to make a personal location application between 2 devices on Android.
The concept is simple: I install my application on my phone as well as on that of my wife and each can geolocate the other.
(This application is strictly personal)
To achieve this, I thought of using sending notifications by FCM.
Telephone A sends a request to telephone B which listens via a service for the reception of a message.
When phone B receives the request, it returns the GPS coordinates via FCM so that phone A displays them on a MAP.
(I also have the possibility to store the coordinates in a database instead of sending back an FCM message)
But FCM's documentation says:
"When your app is in the background, notification messages are displayed in the system tray, and onMessageReceived is not called. For notification messages with a data payload, the notification message is displayed in the system tray, and the data that was included with the notification message can be retrieved from the intent launched when the user taps on the notification."
Of course, this reduces the scope since it forces the user of the phone receiving the notification to click on it to activate the actions of the service.
Can FCM still meet my needs through another channel?
Are there other options to send a "request" to another phone?
(I know that this kind of application exists on the PlayStore, but I want to try to make mine :-))
The key word in that section from the documentation you quote is notification messages. Firebase Cloud Messaging supports two types of messages:
Notification messages, which are display by the system when the app is inactive - and delivered to your application code when the app is active.
Data messages, which are always delivered to your application code.
It sounds like you'll want to use data messages for this use-case
We have multiple mobile clients (ios and android) subscribed to a channel-msg.
7 messages are being published to channel-msg by the server:
Messages 1-3 were published to channel.
The device got messages 1-3 via native PubNub.
The user turned the device off.
Messages 4-5 were published to channel.
The user turned the device on, and app in foreground.
Message 6 is published.
Message 6 arrives to the device.
At this point (in the "got PubNub message" callback in the device's code), I don't want to perform Message 6, because I must perform Messages 4-5 first.
I can use the history() API to get the lost messages, but with this strategy I am forced to perform the "history check" on each message I receive on the device, before I can execute it.
I there a better pattern/design to handle this scenario?
PubNub History
You don't need to call history for each individual message, rather, you retrieve all missed messages (up to 100 per history call).
Just save the timetoken of the last received message in a way that you can retrieve it when the app is relaunched (NSUserDefaults). When your app is launched, just use the timetoken as the end param (nil for start param) in your history call.
If you get 100 messages returned (the max) then it is likely you have more and you need to call history again (paging through storage) and again until you receive > 100 messages.
Once you have received the last of the messages, use the timetoken of that last message (the one closest to now), use that timetoken to subscribe to get any message between the last history call and your subscribe and continue to subscribe for further messages.
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.
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>
}
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.