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.
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
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 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.
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.
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.