I have implemented FCM. The messages are receiving in Android N and lower devices.
dependency
implementation "com.google.firebase:firebase-messaging:17.1.0"
I have tried sending messages from firebase console. It showing in Android N but not in Android O.
I have tried sending data notification from the server. Didn't got any call on onMessageReceived() in Android O.
Added channel while showing notification
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId,
"CRW notification channel",
NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
I have checked this in Samsung S2 and One plus 6.
Do I need to do anything extra for Android O other than setting notification channel on showing the notification?
Did you set your FCM to high-priority.
Add this to your message body:
{
...
"priority":"high"
...
}
High priority. FCM attempts to deliver high priority messages immediately, allowing the FCM service to wake a sleeping device when necessary and to run some limited processing (including very limited network access). High priority messages generally should result in user interaction with your app. If FCM detects a pattern in which they don't, your messages may be de-prioritized.
Ref: https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message
Check this on server side the push message is sent as Data Payload or Notification
For android version greater than M it requires to send notification in Data Payload
By passing send Data (on server side).
Also works when app is running in background.
Related
I'm sending data payloads through FCM and handling them in the onMessageReceived() method of FirebaseMessagingService. The problem is, when the app is in the background, the push notifications seem to be popping up each time the device handles them. I'd like them to be silent similar to how Android delivers notification payloads.
How do I make sure the notifications do not create this popup effect? I'm on Android 9.
Here's how the notification is generated on the client:
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, myChannelId)
.SetContentTitle(title)
.SetContentText(body)
.SetSmallIcon(Resource.Mipmap.ic_launcher)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
and this is how it's notified:
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
notificationBuilder.SetChannelId(myChannelId);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(myId, notificationBuilder.Build());
Notifications will appear with a popup effect ('Heads Up') view like shown in the screenshot if you set the notification channel priority to IMPORTANCE_HIGH or above, so to stop that happening, you should ensure the channel priority is IMPORTANCE_DEFAULT or lower.
If you have other notifications that you do want to use the heads up view, then you should create a separate NotificationChannel for this notification. Note that notification channels appear as 'Categories' in the notification settings for your app, allowing the user to choose which kinds of notifications they want to see from you, and two notifications wanting a different priority is a good indicator that they should be in different categories
When app is killed / in background...
When only 'data' payload is passed in request, notification will be generated with popup, and handled by user in 'onMessageReceived'
When only 'notification' payload is passed in request, notification will be generated without popup, and handled by android OS
When both 'data' and 'notification' payload are passed in request, notification will be generated without popup, and handled by android OS and data will be available for handling in extras of the intent.
So, in our case (don't want to show notification as popup) pass both 'data' and 'notification' payloads in request params. (Here title and body will be shown, what is passed in notification payload)
Refer official link: https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages
Use android lifecyclehandler and check whether app is in foreground or background and don't show the notification if app is in foreground lifecyclerhandler
Actually I tried to send notification for single device through Test On Device option in Console. It shows completed but notification not received by device. And then I tried postman and pushtry.com, both of them gave result "Firebase Push Notification Sent Successfully", even though the android device(Google Pixel Version 9) not received. Please help me to resolve this problem.
You are probably not having a Notification channel in your MainActivity you can configure it something like below:
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager) GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
And then call it from MainActivity's OnCreate Method
Minimize your application(for example go to dashboard or lock the phone) and send the FCM push notification. If you able receive the notification in this case, that mean you FCM is configured properly. The code you share will only work if you app in in background. IF you wish to receive the notification when app is in background. You have to implement inherit FireBaseMessagingService call and override OnMessageRecived method.
I'm having an issue where Firebase Cloud Messaging will send notifications to the emulator (Android 7.0, with play services installed) but not to any device (Google Pixel 2, Samsung s9+ , Huawei MATE 10) running Android 8+. I initially thought it might have been a power saving issue closing off the listener but even when I remove optimisation from the app, it still doesn't come through.
I know the downstream request is being sent successfully and I'm receiving status code 200 from the response (and of course because the notification is being received on the emulator). When debugging on the devices however, the onMessageReceived in my FCMService class is not being called at all, whether in the foreground or background.
It's definitely registered in the manifest and each device is using the same version of the application:
<service android:name=".services.FCMService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
If there is any more information required, let me know. Thanks in advance.
Why was this happening?
I realised when I entered the version numbers into the question that it would have to do with Android Oreo. I was searching for issues with FCM and not recent changes the how notifications work. In Android 26+, notification channels have been introduced and are required if your app is targeting 26 and above (which I was). Because I updated the target SDK without thinking, I of course got hit with no notifications.
How to fix it
The easiest way is to just target API 25 but that's not ideal.
What you can do is register notification channels. I've done this where I handle my notifications (so onMessageReceived) as it doesn't register the same channel more than once.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Set the default notification channel settings to be that of alert
int importance = NotificationManager.IMPORTANCE_HIGH;
String channel_id = ALERT_CHANNEL_ID;
CharSequence channel_name = ALERT_CHANNEL_NAME;
String channel_desc = ALERT_CHANNEL_DESC;
// Logic to change the channel id, name and desc if required
// Build and modify channel settings
NotificationChannel channel = new NotificationChannel(channel_id, channel_name, importance);
channel.setDescription(channel_desc);
channel.enableLights(true);
channel.enableVibration(true);
// Create the notification channel
notificationManager.createNotificationChannel(channel);
}
Then you want to change the notification builder:
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channel_id)
I have implemented FCM push notifications in an android app.
While I am logged in to the app. I get the notification in the form that I am expecting as below.
When the app is in background I receive the json response instead as below.
Following is the code I have added in onMessageRecieved()
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle("App")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(bitmap))/*Notification with Image*/;
How can I get the notification in the same manner in both cases.
Any help will be appreciated thank you
After setting up FCM in Android application, you can use Firebase console to send notifications. When foregrounded application receives a notification, onMessageReceived method is invoked. You should override this method to handle notification, but the problem is when the application is in the background and receives a notification, notification delivers to the device’s system tray and you can not handle notification with onMessageReceived method. When the user taps on a notification, it opens the app launcher by default. For example consider you want to do a specific task when a notification is received to the user or do something in background without the user realizing or don’t want to show notification dialog to the user, you can’t do these when the application is backgrounded.
Message Types
With FCM you can send two types of messages to clients :
1- Notification message, sometimes thought of a “display message”
2- Data message, which are handled by the client application
According to Google documents a notification message has a 2KB limit and a predefined user-visible keys. Data messages let developers send up to 4KB custom key-value pairs.
Solution:
If you want to handle notification when the application is backgrounded you should send data message and use onMessageReceived method.
Here is the complete article.
That is so because push notifications handles in foreground and background in different ways.
From the documentation
Notification messages delivered when your app is in the background. In
this case, the notification is delivered to the device’s system tray.
A user tap on a notification opens the app launcher by default.
Messages with both notification and data payload, both background and
foreground. In this case, the notification is delivered to the
device’s system tray, and the data payload is delivered in the extras
of the intent of your launcher Activity.
Also you have to remember that there are 2 types of firebase pushes - Notification message and Data message.
Looks like you are using Notification messages, so they are working as expected.
Just use data type of messages and so you can always handle them as you need.
I have a strange issue. I have two way to send notifications in my Android app; one from the Android service and the other through FCM.
The scenarios are as follows:
Regardless of whether the app is running or not, the icon of the notification sent from the Android service appears correctly.
When the app is running, the notification icon appears still appears correctly if I send the notification via FCM.
But if the app isn't running and I send the notification via FCM, a white square is displayed instead of the notification icon.
My code in FCMService:
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Android App")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
Most likely your problem is the difference between notification-messages and data-messages.
Please read: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
Use notification messages when you want FCM to handle displaying a
notification on your client app's behalf. Use data messages when you
want to process the messages on your client app.
Currently the FCM Web Console only sends notification-messages
So all the messages sent via Web Console (or via API with a notification payload) will be have in this way:
if the app is closed or in background: FCM will display the notification. if you want to customize it you can, but you need to provide specific configuration (in the manifest or in the send API call) see https://firebase.google.com/docs/cloud-messaging/android/client#manifest
if the app is in foreground: FCM will call onMessageReceived()
.
If the behavior that you want is that onMessageReceived() is always called:
then you need to use a data-only (no notification) message
This is a FMC bug detailed in github fcm page.
https://github.com/firebase/quickstart-android/issues/4