FCM background notification in Oreo and above - android

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.

Related

Difference between the two types of FCM push notification payloads (notification vs data) and when do they arrive to Android FirebaseMessagingService?

In Firebase push notifications, the payload can be of type "notification" or "payload", but they arrive (or not) depending on whether the app is in background or not and other details. Please clarify them.
(This answer focuses on Android devices)
Firebase Cloud Messaging (FCM) push notifications can be of three types : notification, data and notification+data.
Notification messages are meant to be received by the Android operating system itself, with no intervention by the app. When received by Android, they will be shown as a notification in the tray. Some details:
The tray notification will not be shown if received when your app is in the foreground.
You can implement a FirebaseMessagingService (see the data payload for more info on this), which will receive the message if your app is in the foreground. In your FirebaseMessagingService, you can show a tray notification yourself (or do whatever you want) when you receive the message.
When sending the message, you can specify what happens when the user clicks on the notification; this can be controlled by either specifying an activity in the click_action Android-specific option (see this) or by specifying an URL in the link property and having your app configure an intent filter associated with the URL you specified.
Data messages are meant to be received by an Android service of your app. This service can, in principle (see below [*]), receive the messages when your app is in the foreground, in the background, or not running at all. Some details:
To implement the service, you have to extend FirebaseMessagingService and configure it in your app's manifest.
When you receive the message in your FirebaseMessagingService, you can decide to emit a local notification to be shown in the tray. You can do this either when your app is in the background or in the foreground, in principle (see below [*]). Of course, you may also decide to do other stuff instead (or apart) of showing the tray notification.
[*] Some phone manufacturers, especially Chinese ones like Xiaomi and Oppo, implement some mechanisms to save battery that include killing services. This means that, by default, your FirebaseMessagingService will not be running on those phones unless your app is on the foreground and, therefore, it will NOT receive your data payloads when your app is not on the foreground. There is no way around this, except if the user whitelists your app specifically. The famous apps like Whatapp or Gmail are by default included in the whitelist, but yours won't; therefore, if you rely on data payloads and you want your app to work on that kind of phones, you'd better guide your user to configure their phone to allow it; here you can see how to do it for Xiaomi (Miui) devices. This can also happen in vanilla Android devices since Android 9 (API level 28) with background restrictions, but the behaviour is opposite: your service won't be killed unless the user requests it; you can check this with ActivityManager.isBackgroundRestricted
Notification + data messages include both types of payloads. They behave exactly like notification payload-only messages:
When your app is in background, Android shows the notification in the tray. The data payload is accessible to the app if it receives the intent invocation when the user clicks (described above) in intent.extras.
When your app is in foreground, your FirebaseMessagingService receives the notification with the contents of the data payload.

Service to keep alive FirebaseMessagingService even if app is not running and show notifications with Data payload

I am working in a application that uses FCM notifications, when app is running (foreground or background) the notification receives but when i clear the app from my recent apps i do not receive any notification i am using FirebaseMessagingService. So i want to create a service that will keep alive myService which is extending FirebaseMessaging service even if app is not running or killed.
I found a reason for this problem
when you Release-APK is not from GPlay some mobile companies block services which want to auto start the app. you can do two think first download app from GPlay or in your phone settings disable battery optimization for your app or permit your app auto start.
I've tried everything - in my opinion theres no reliable solution to prevent any service from being killed.
The only way is to make sure to deliver the notification to the system tray not to the application.
There are 2 types of FCM notifications: Notification message and Data message.
Data messages are delivered to system tray and are always display - even if service is not running.
Notification message looks like:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
and triggers method OnMessageReceaved() of FirebaseMessagingService. Many devices (especially Huawei and Xiaomi) try to do everything to kill background services to prevent battery drain. So the FirebaseMessagingService isn't the best way to handle notifications.
Second type is
Data message:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
This type is handled by the system tray, so you don't need any of service running to get the notification. Its much more convenient method, but as far i know, it can't be achieved with the console.
You would probably need server API to send Data message.
Read this for more details.
When the application is killed. You need to push silent notification (payload without notitication property) to handle in the FirebaseMessagingService.
You can refer this link: https://firebase.google.com/docs/cloud-messaging/concept-options
You will need to use Data-Messages from FCM to have control of your notification payload, by using Data-Messages your app's onMessageReceived will be called even if your app is in background or killed, you will have to create a custom notification yourself to show your payload.
On the other hand I used Notification-Messages in FCM, they were delivered even if the app was killed.

Firebase Data message not handled by FirebaseMessagingService when app is in Doze mode

I am sending "Data" messages with Firebase to my app, but when the app is in Doze mode, those messages are not handled by FirebaseMessagingService, even when my app is whitelisted for battery optimisation and my messages marked as priority.
Firebase docs on why I choose "Data" messages instead of notification.
Android mechanism to add app to whitelist and skip battery optimisation.
Firebase priority messages according to documentation.
I follow all this steps, and even after this, messages are not handed to my implementation of FirebaseMessagingService.
Any idea how to force messages be handed by FirebaseMessagingService, even in Doze mode?
Note: I'm working on a VoIp app, if message its not immediately handed, its no longer valid and the purpose of it is lost.
If you are following all the documentation, it may still be the case that FCM has deprioritized your messages, as described in the documentation:
High priority messages generally should result in user interaction
with your app or its notifications. If FCM detects a pattern in which
they don't, your messages may be de-prioritized. Android P introduced
app standby buckets which limit the number of FCM high priority
messages you can send to your app that don't result in the user using
your app or viewing a notification. If, in response to a high priority
message, a notification is displayed in a way that is visible to the
user, then your app standby bucket quota will not be consumed by that
message.
There is no "force" mode that lets you operate above the rules stated in the documentation. If anyone could simply bypass the rules, then everyone would do it, and the rules would become useless to the end user, who is just trying to save their battery from apps that aren't following best practices.
After a while we found out the problem.
In server side instead of implementing the newest API the legacy one was implemented.
They have a different payload that can be seen here: Firebase Payload
basically instead of :
"android":{
"ttl": "0s",
"priority": "high"
}
we had to use:
"priority": 10,
"time_to_live": 0

Is it possible to receive FCM push notifications when app is killed?

I am developing an e-mail app in which I want that the user will get a push notification as soon as they receive new email. And for that purpose I am using FCM. I have just tried push notifications using FCM by following this link: https://www.youtube.com/watch?v=XijS62iP1Xo&t=6s in order to test what features FCM provides. But the problem I face is that the device receives push notifications when app is either in foreground or background but it won't receive any push notifications when the app is closed (swipe or clear from the task manager). I don't know how to achieve this via FCM? I want to receive push notifications just like the WhatsApp and Facebook apps.
Every kind of help is appreciated. Thanks in advance.
There are 2 types of push notifications: Data messages and Notification messages.
If you are using the Data messages you will be in charge of handling the received message and present a notification to the user (if needed of course). But in this case you might miss notifications when your app is closed.
If you are using Notification Messages, FCM is handling the message for you and directly displays a notification if the app is in background/closed.
Please see more here.
It is not possible to receive a push notification in an app that has been killed/stopped by "Force stop" in application settings:
Let me quote the response I got from Firebase Support when I posed them that question:
The Android framework advises that apps that have been stopped (i.e.
killed/force-stopped from Settings) should not be started without
explicit user interaction. FCM follows this recommendation, and thus
does not deliver messages to stopped apps. Here are some documentation
that discuss this topic:
Life of a message from FCM to the device Using Firebase Cloud
Messaging with Android O
This confirms what I observed when I tested it using a simple app.
But you should be able to get push messages from FCM when the app is in background, even if it was swiped off from Recents screen, or after system reboot. That is, unless the manufacturer made the swipe gesture to work the way "Force stop" does on your device. How you receive it in the background depends on whether the push notification contains the "notification" payload:
If it does, you will receive the "data" only if user taps on the notification and it will be delivered in the Intent extras to the activity launched by the notification action.
If it doesn't, you will receive the notification in onMessageReceived just like you do when the app is in foreground.
Some other cases when your app is not killed, but still may not receive push notifications:
there can be delays because of Doze mode if you don't use high priority for the push message
message might not be delivered if your app is background restricted
Yes only if you consider sending data payloads not notifications and handle it in onMessage()
get more info here
How to handle firebase notification on background as well as foreground?
If your App is Killed or in background,check for the Payload in your Launching Screen
in My case it is MainActivity so in onCreate() Check for Extras:
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
}
}

What is the difference of "Notification" and "Push Notification" in Android

I want to use Notification in my Android app but I don't know what is the difference between Notification and Push Notification in Android.
I searched the web about this title but all of them talk about differences in apple products.
Can anyone remark where I should use Notification and where I should use Push Notification?
The main difference between push notification and notification is that the latter are created internally from an application on the device that wants to show user some information, a reminder, some news or updates, and so on. Push notification are "messages" sent from outside the device, for example a server, that triggers an application of the device (which usually handle the incoming message and transform it in a "normal" notification to be displays in the system tray). This is usually made through a public service such as Firebase Cloud Message ( https://firebase.google.com/docs/cloud-messaging/ ) of Google or a proprietary service such as the one that is used by the most common chatting application (Whatsapp, Telegram, ...) .
Indeed the most common example of push notification is the whatsapp notification of new messages that shows up in your phone when another user has sent you a message (so the message comes from outside your phone). Instead, the basic example for normal notifications are the alarm's notifications or the calendar's notifications.
Notification: When notifies you about the same application state, example: In a game application: "You have 10 days trial, or a product that provides the application".
Push Notification: When notifies you in real time about events related to users, eg solical In an application, "A message from a friend, a new invitation, an event".

Categories

Resources