My app server written in GO language is sending notifications to the device through FCM / XMPP. When i set delivery_receipt_requested to true, i am not receiving delivery status message every time.
For testing purposes, i made test app that sends push notification every second with delivery_receipt_requested to true. For 10 notifications, i am receiving only two or three (sometimes not even one) delivery status message, and on android app all notifications are delivered.
I tried two FCM / XMPP Go libraries, but both of them have same behavior (Go-FCM, Soygul GCM)
On android device, latest Google Play Services are used (at the moment 10.2.4)
Is this common behavior, or am i missing something?
Related
I've been reading about non-standard app killing on https://dontkillmyapp.com/. In particular, I'm worried about how manufacturers are implementing mechanisms under the name of 'battery optimisations' which cripple the local notification API, by cancelling all alarms scheduled by an app after some time of inactivity: AlarmManager not working in several devices
Since there is no fix we as developers can implement to make local notifications work reliably, I'm wondering if I can just switch to push notifications. But I'm also not sure whether I can rely on push notifications, as there seems to be conflicting information:
Signal seem to say that their push notifications may be unreliable when battery optimisations are at work, though it's not clear whether this only applies to their custom web-socket push notification system, which it apparently uses when FCM isn't available: https://support.signal.org/hc/en-us/articles/360007318711-Troubleshooting-Notifications#android_notifications_troubleshooting_phone
It seems that push notifications which are sent via Firebase Cloud Messaging (FCM) will actually be received by the Google Play Services, so is it possible they may be received even if your app has been 'battery optimised'?
Can anyone shed some light on this? Can push notifications via FCM be more reliable than local notifications, when working around non-standard app killing?
Push notifications will work but still they will be affected by battery optimizations. Things like Doze mode will make your app poll-rate depend on things like user's usage of the phone; battery-level and etc.
There are things that we just cannot fight as developers and if the underlying OS decides that your app won't wake up it's better that the user gets a better phone...
Apparently using FCM is no guarantee that notifications will be received - they may still fail to show due to non-standard battery optimisations.
This is documented by the following article:
https://hackernoon.com/notifications-in-android-are-horribly-broken-b8dbec63f48a
Which states that:
Google GCM said that the notification was sent but there was no trace of the notification in the app’s logs, it was as if the OS was swallowing notifications
After disabling battery optimisations, the notifications apparently worked again. Their workaround to this issue was:
GCM delivery receipts essentially tell you whether the device received the push notification or not. We coupled this with duplicate notification delivery receipts from inside of the app. So any device where we got ack’s from GCM but not from the device, was potentially missing pushes. Once the devices were identified, we started sending them bot messages on how to add flock in their device’s auto-start list.
Due to numerous app restrictions by android including Doze Mode and different OEM having their own implementation of battery optimization.
So I found out that GCM services is always running, is there a way for FCM to handle notification in background on its own?? Without depending on my app or app state?
I only send notification message which I want the FCM to handle without my app, because my app might be forced stopped or killed by app killers.
Can FCM just handle notification without my app's involvement?
FCM documentations states that
With FCM, you can send two types of messages to clients:
Notification messages, sometimes thought of as "display messages." These are handled by the FCM SDK automatically.
Data messages, which are handled by the client app.
In your case, it seems that you are looking for Notification messages. In short, FCM will automatically display a standard android notification with a title and a message (body), when your app is in background.
To get this to work, the notification needs to be sent through Firebase (for example using the firebase console or cloud functions) and it needs to contain the notification key like in the following sample:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
For what regards your app's side, it mainly just needs to be setup as a Firebase client. If in any case you want to receive/display the notification also when your app is in foreground, then you'll have to create a service that extends FirebaseMessagingService as explained here
Bonus: since it looks like your target is android 8+, you may also want to look at Notification channels as every notification must be assigned to a channel in order to be displayed. By default, you'll get one with basic settings.
When we disable push notifications at app level:
Does the OS automatically unregister the app from GCM/FCM ? (i.e) Will the GCM/FCM stop sending messages to the client for that app.
Will the push event listener code block be executed (minus UI tray) even when push is off at app level ?
Does the OS automatically unregister the app from GCM/FCM ? (i.e) Will the GCM/FCM stop sending messages to the client for that app.
Yes. The GCM/FCM server doesn't determine if the device has disabled notifications for the corresponding app. So long as the device was targeted for the message, GCM/FCM will deliver the message.
Will the push event listener code block be executed (minus UI tray) even when push is off at app level ?
FCM for Android works differently depending the message payload type you sent. However, depending on the device, usually when Notifications are disabled, regardless of notification type, it would be blocked by the OS.
For more infos:
SO post
Received message in Android App
Can Firebase console push notification if apps is closed
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)
I just started developing with Parse's Push Notifications. I'm using them for pushing to Android right now and when I just started off, the notifications were delivered fast (instantaneous delivery).
However, as I'm sending more and more notifications to the same device - I'm noticing that it is taking about 10 minutes to deliver the notifications. Is this normal? If not, is this an issue with Parse or GCM?
Is there any way to "simulate" the notifications for development purposes so that they can be tested?
I'm generating the notifications from the REST API and have a Wifi enabled device.
According to my experience in GCM or any other related service, should only be used if you have to push notification to some target devices i.e. to selected users from your database.
--For Higher scalability and maintainability
You should make background service instead to fetch the notification and create a api for that, as there would be direct integration through your server, its is reliable fast and it has higher accuracy.
Whereas gcm does make a background service and hit gcm server and responds accordingly, but sometimes it misses the notification or delay as per the server load.