Will 'Sleeping' apps receive push notifications from FCM? - android

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.

Related

How GCM/FCM alternatives work internally to overcome OS challenges

For devices that don't have Google Play Services, there are a few options to be able to receive push notifications.
Those options can be Baidu in China, Pushy, Facebook own push notifications, etc.
But I cannot understand how is that even possible to overcome those two main problems :
Since we cannot have an "SDK" of some sort like the Google Play Service on a device-level, our only option is to integrate it on an app-level. This means, we cannot have one socket connection to the push server that would be mutual for all apps, like the GCM does. Instead, we need to have as many socket connections alive as the number of apps installed.
Even if we close an eye on problem number 1, to make that connection survive Doze and App Standby, we would have to handle them in a Foreground Service, which is the only way to guarantee its running even after killing the app, or when the device enters Doze state.
But how come we don't see the notification of a foreground service in the notification bar in Chinese phones, or apps that use Pushy for example?
Are they simply polling the push server periodically? with AlarmManager (marked with setAndAllowWhileIdle) and a BroadcastReceiver ? that would be too resource-heavy and inefficient.

Firebase data payload not delivered when app is in Doze on Wear OS

We have a Wear OS app, which relies heavily on Firebase messages. We send data only messages from pyfcm and we handle them inside onMessageReceived(). All messages are with high priority. This seems to be working properly for some time, which varies - can be between 10 minutes and few hours.
After some time we stop receiving messages. From the documentation I know that a high-prio data message should wake up the device even in Doze - unfortunately this is not happening.
What we believe it is happening is that FCM is de-prioritizing our notification because of low interaction pattern. The issue is that his is core functionality and we can't change that.
Any idea how we can overcome this issue?
I don't believe that the problem is that FCM is de-prioritizing your messages. The problem could be how your app is handled by Wear OS when in Doze mode.
A similar issue is present in android smartphones. They don't receive push notification from FCM when user swipes the app from the system tray because, due to brand specific battery saving reasons, the services needed to handle push notification (MessagingService and InstanceIDService) are not running in the background. To have an idea of the issue on smartphone see this: Firebase Github issue.
Probably after some time that your app is in background it gets killed by the OS in order to save battery, so then the services are not running and it doesn't receive notification anymore.
Anyway without some further explanation on how the app works and without any code I can only make a guess.

Android custom independent push notifications

How can I implement push notifications on Android without using Firebase cloud messaging and Google play services. I would use MQTT, but I don't know how would I handle it on Android client. Background services are very restricted since Oreo, and I see no way of keeping reliable connection to MQTT broker when app is in background.
I was thinking AlarmManager and starting scheduled jobs to check for new messages, but Android seems to ignore that while in "Doze" mode.
I could have foreground service running constantly but that just seems wrong.
Maximum tolerable latency between sending and receiving notification is 20-30 seconds.
There are some 3rd party services that offer push notifications, how are they doing it?
I need to be independent of FCM because Google is blocked in China, and that's my use case.

Push notifications arrive after a long time on some devices

On Android, I have been experiencing long push delay in some devices (minutes, half an hour). Seems like the device is asleep (but not for WhatsApp). Even on Pre-Marshmallow devices.
After a while they don't respond to push.
I have created a simple app (copied Google's Cloud Messaging client sample).
Tried to send push via The Firebase Console, setting priority to HIGH and made sure it works.
Experiment 1: After a while - tried to send. The device is not responding.
Experiment 2: Tried to use Telegram and WhatsApp. Message passes immediately on both.
Experiment 3: Tried the my test app again. Not working.
Experiment 4: Tried to downgrade from FCM to GCM and all the way to C2DM. Same thing, not working.
Any ideas?
To make it clear:
The token is okay. In most cases it works. It just falls asleep after a while.
It's a Lollipop device so no Power Saving exempts here or battery saving.
I use priority:high on the payload.
It is no server issue because I use FCM composer and it's just the same.
Waking the device does not necessarily fix it. It just begins to receive notifications minutes later and then all ok.
Other apps such as WhatsApp work without problem whatsoever, always.
I tried C2DM, GCM, FCM. I am using a printout on the C2DM receiver. They all behave the same.
I log everything. Every event, broadcast I get. I don't get push when I should.
Possible clue: some of my customers are using VMWare AirWatch. anybody know about any issues related to AirWatch and Push?
This is not a complete answer so I can't mark this question "Answered".
I found some alternative push mechanism called Pushy. It's mentioned quite a lot in Stack Overflow.
Pros:
I have made tests on a phone where FCM and GCM failed. Pushy succeeded to deliver all my messages, always.
It can work on devices with no Google Play Services enabled
It is also a workaround for the SERVICE_NOT_AVAILABLE issue.
They have a nice friendly console like in FCM, where you can send test messages.
You get a feedback when the message was delivered to Android devices.
Has topics like in FCM so you can send one message to a group.
Cons:
Money. It costs. Not too much. Last time I checked it was 0.5Cent per month for each active user. It may be a lot but my app is an emergency app so availability is a must in my case.
Does not have retries like FCM, as far as I understood. I may be wrong but it does not handle many things that FCM does. It may not do exponential back-off retries or Notification Messages A-la-Apple. I personally hate FCM behaviour on that so I am fine with this.

Send push notifications on android without using C2DM

Is it possible to send push notifications to an android application without using Google server: C2DM?
So, I would like to have my own server which sends notifications directly to the app, but I'm not sure how are the notifications perceived by the device, because the device needs to receive notifications even if the app is not running and the notifications should appear in the notification center.
I think that the guys from www.airpush.com have managed to this, but I'm not sure how.
Can anyone help me with this please?
UPDATE:
Also I would like to know how to display the notifications in the notification center if I don't use C2DM? And if it is possible to configure the notification center to receive notifications from my server even if the user deletes the application developed by us, application which registered that device to receive notifications.
I want to send 3-4 notifications a day, but these notifications need to appear in the notification center and they should go only through our server. How can I configure the notification center within the app to make requests on my server for push notifications.
Thank You!
There is a solution from UrbanAirship called Helium push. According documentation Helium:
Works on Android 1.6 and higher
Does not require a Google Account
No default pushes per day limit
No default pushes per minute limit
Works on Amazon devices (e.g., Kindle Fire)
End to end Urban Airship support (i.e., API to to device)
Best throughput
The problem is that you need development app key for using this one.
Take a look at MQTT:
MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks.
It can be used (and was used in some applications) to implement custom server push solutions. One of the most well known applications using MQTT is Facebook Messanger.
You can easily find more information on MQTT in the Internet, e.g. in this SO question or in this blog post.
According to the FAQ on airpush.com, they're not using real push notifications but rather polling the server a few times per day. One reason I think this is a viable solution for you as well is that Android's C2DM apparently makes use of the Google Play Store, so it won't work on devices distributed outside of the Google eco-system. With over 5 Million Kindle Fires having sold already, that is worth thinking about.
From Airpush FAQ:
When executed once from the main activity of an Android™ application, the Airpush client utilizes Android™ OS's AlarmManager framework to schedule ongoing server polling events a few times per day. If an ad is polled from the server it is cached until optimal display time, which is algorithmically determined by the server.
Without using C2DM there's not option for a "real push notification". Because (afaik, correct me if I'm wrong) an android device registers at google (they can still deinstall malware from your phone via remote) and with this ip they are able to do a push notification. All other solutions could tend to be a "register at a server, keep the connection alive and wait for requests" or something and tend to be more battery-inefficient.
Parse has an excellent push notification service for Android, very easy to setup. More info here: Parse Android Notification Doc
If you want the user to only receive 3-4 messages per day and your messages are not bound to specific arrival times, you don't need pushing mechanisms.
Just create a service in your app that checks your own web service 5-10 times a day. If there is new data, make your app display it in the notification center.
If you don't want to have a service running all the time (like many messaging apps do), you can set up alarms (using the Android AlarmManager framework) that wake your app up regularily to check for new messages to display.
And if it is possible to configure the notification center to receive
notifications from my server even if the user deletes the application
developed by us, application which registered that device to receive
notifications.
That sounds like you want to write a virus or root kit ;-) You could use e-mails for your messages instead.
UPDATE 2013-12-30:
As just noted in my comment, rebuilding what GCM does is not a nice approach. It's enough when Google Services already load the device with this functionality. If your goal is just that Google does not see what messages you send to your users, you might aswell encrypt them. For Google not being able to actually read your messages, the client app should generate a key and send it to your server. All messages you send via GCM can then be encrypted using that key.
If you just want to circumvent Google's restriction on the amount of messages sent to users, you could pack multiple messages into one GCM notification and show them one after the other. But then again, we are back at some kind of polling solution as described before, with the exception that the user does not need to have internet access when you want to show the messages as they are cached on the device.

Categories

Resources