I've read the ~10 similar questions to this on SO, and some other google search, and documentation pages, and I still can't figure out what the issue is.
Basically, if the app is closed (or backgrounded), the push notification icon shows up as a white square.
If the app is running, it shows up with the icon I want.
My icon is transparent, and just white. Its a simple icon that comes from Google itself.
Here's what I have, and where the issue may be.
Our app has multiple modules. I'll focus on 3 of them:
App
AppCode
PushNotification
I'm building the local notification on the PushNotification module:
override fun onMessageReceived(from: String?, data: Bundle?) {
super.onMessageReceived(from, data)
Log.d("PNReceiver", "onMessageReceived")
val notification = data?.get("notification") as Bundle?
val notificationTitle = notification?.get("title") as String
val notificationBody = notification?.get("body") as String
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = getString(R.string.notification_channel_id)
if(manager.getNotificationChannel(channelId) == null) {
val channel = NotificationChannel(channelId,
getString(R.string.notification_channel_name),
NotificationManager.IMPORTANCE_DEFAULT)
channel.description =
getString(R.string.notification_channel_description)
manager.createNotificationChannel(channel)
}
createLocalNotification(manager, channelId, notificationTitle, notificationBody)
}
}
private fun createLocalNotification(notificationManager: NotificationManager,
channelId: String,
title: String,
body: String) {
val largeIcon = BitmapFactory.decodeResource(resources, R.drawable.ic_cake_variant)
val builder = NotificationCompat.Builder(this, channelId)
.setContentTitle(title)
.setContentText(body)
.setStyle(NotificationCompat.BigTextStyle().bigText(body))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setSmallIcon(R.drawable.ic_cake_variant)
.setLargeIcon(largeIcon)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND or Notification.DEFAULT_LIGHTS or Notification.DEFAULT_VIBRATE)
notificationManager.notify(0, builder.build())
}
Also, I'm trying to push the exact same icon, on the manifest of the PushNotification module:
<application>
... some gcm stuff...
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/notification_channel_id" />
<meta-data android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/ic_cake_variant" />
</application>
The other 2 modules (App and AppCode) don't have anything related to the push notification code.
FWIW, our data flow/dependency graph of modules is App -> AppCode -> PushNotification
Also, we're still using GCM and not FCM, on version com.google.android.gms:play-services-gcm:11.8.0
Tried version 15.0.1, with no success either.
Am I missing something super obvious?
Thank you for your help.
UPDATE
Here's what the body of the received message looks like:
Bundle[{
google.sent_time = 1526919xxxxxx,
google.message_id = 0: 1526919xxxxxxx % xxx c5e8a46xxxxxx,
notification = Bundle[{
body = test message 1,
title = test title 1
}],
message = test message 1,
collapse_key = com.mycompany
}]
Also, here are some of the other answers I've reviewed:
Question 1
Question 2
Question 3
Related
I want to show the app name on top and all the notifications of the app clubbed below it. I am receiving the notification from firebase and using this code:
val messagingStyle = Notification.MessagingStyle(person)
val remoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).also {
it.setLabel(context.getString(R.string.type_to_reply))
}.build()
val mChannel =
NotificationChannel(channelId, newMessage.text, NotificationManager.IMPORTANCE_HIGH)
mChannel.description = newMessage.text.toString()
mChannel.enableVibration(true)
val notifManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notifManager.createNotificationChannel(mChannel)
val statusBarNotification = notifManager.activeNotifications.firstOrNull {
it.id == channelId.toInt()
}
if (statusBarNotification == null) {
val builder: Notification.Builder = Notification.Builder(context, channelId)
val pendingIntent: PendingIntent =
PendingIntent.getActivity(
context,
channelId.toInt(),
navIntent,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
builder.setContentTitle(newMessage.text)
.setSmallIcon(R.drawable.my_logo) // required
.setContentText(newMessage.text) // required
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.addAction(
getNotificationIntent(context, channelId.toInt(), remoteInput)
)
.setWhen(newMessage.timestamp)
.setStyle(messagingStyle.addMessage(newMessage))
.setContentIntent(pendingIntent)
.setGroup(MY_NOTIFICATIONS)
.setGroupSummary(true)
val notification = builder.build()
notifManager.notify(channelId.toInt(), notification)
} else {
var notificationBuilder = recoverBuilder(context, statusBarNotification.notification)
notificationBuilder.also {
val messageStyle = it.style as Notification.MessagingStyle
messageStyle.addMessage(newMessage.text, newMessage.timestamp, person)
it.style = messageStyle
}
notifManager.notify(channelId.toInt(), notificationBuilder.build())
}
This is what I want(like whatsapp)
[![whatsapp screenshot]]
[1]: https://i.stack.imgur.com/1j3Xf.jpg
But this is how it is appearing right now. all the notifications are seperate.
[![screenshot]]
[2]: https://i.stack.imgur.com/UdhrY.jpg
There are similar posts here about merging notifications. They offer different approaches so check them out to see which one is applicable to your use case:
Firebase merge similar notifications in Android
How to merge push notifications like whatsapp does in FirebaseMessagingService
Can't get grouped/bundled notifications with
FirebaseMessagingService
I am trying to show a custom notification when I get a push notification from firebase, when the app is in background.
When the app is in background, the log messages START and END gets printed but does not show the notification on Android which I created as customNotification.
This is how I created a notification.
Could you please suggest what should be corrected please
override fun onMessageReceived(message: RemoteMessage) {
Log.d("FCMService", "onMessageReceived START")
//super.onMessageReceived(message)
// Get the layouts to use in the custom notification
val notificationLayout = RemoteViews(packageName, R.layout.plugin_requires_approval_notification_small)
val notificationLayoutExpanded = RemoteViews(packageName, R.layout.plugin_requires_approval_notification_large)
// Apply the layouts to the notification
val customNotification = NotificationCompat.Builder(this, "FcmService")
.setSmallIcon(R.mipmap.ic_launcher)
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(notificationLayout)
.setCustomBigContentView(notificationLayoutExpanded)
.build()
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, customNotification)
Log.d("FCMService", "onMessageReceived END")
}
Thanks in advance
R
EDIT
it is fixed now, the issue was with the CHANNEL_ID I provided.
for reference channelID should be the one used in the notificationChannel() function which looks like the bellow code, this is in the project App class.
private fun createNotificationChannels() {
// Do this only on API 26+ because the NotificationChannel
// class is new and not in the AndroidX library
if (SDK_INT >= O) {
val caInfoNotifChannel = NotificationChannel(CaInfoProcessingService.NOTIFICATION_CHANNEL_ID,
getString(R.string.ca_info_service_notif_channel_name),
IMPORTANCE_LOW).apply {
description = getString(R.string.ca_info_service_notif_channel_desc)
}
// Register the channel with the system
getSystemService<NotificationManager>()?.createNotificationChannel(caInfoNotifChannel)
}
}
I have been getting a blank/grey notification icon on some Android devices (Pixel 2 XL and Pixel 5 - both Android 11), but it shows up fine on other Android devices I tested on (Huawei P20 & P30 - both Android 10). Has anyone else come across this anomaly?
This is what I tried:
I have ensured all icon sizes follow the defined bitmap
densities using the Android Asset Studio.
I also added the the .setColorized() method to the
Notification.Builder object as it was previously missing in the
code, but that made no difference at all. I have included my
notification code below:
private fun sendNotification(title: String?, message: String?, intent: Intent) {
val pendingIntent = PendingIntent.getActivity(
this,
0 /* Request code */,
intent,
PendingIntent.FLAG_ONE_SHOT
)
// With the default notification channel id the heads up notification wasn't displayed
val channelId = getString(R.string.heads_up_notification_channel_id)
val notificationBuilder =
NotificationCompat.Builder(this, channelId).setSmallIcon(R.mipmap.ic_stat_ic_notification)
.setAutoCancel(true)
.setColorized(true)
.setColor(ContextCompat.getColor(this, R.color.color_orange))
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent)
if (title != null) {
notificationBuilder.setContentTitle(title)
}
if (message != null) {
notificationBuilder.setContentText(message).setStyle(
NotificationCompat.BigTextStyle()
.bigText(message)
)
}
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,
"Test",
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(Random.nextInt()/* ID of notification */, notificationBuilder.build())
}
I have had a similar Issue before. In my case the problem was the icon that I tried to use. I used a non-PNG file for the icon of the notification. When I switch it to PNG format, the nofication worked normally for all devices I tested.
If you are not using Png format for the icon , you can try this way.
Also, the problem can be the size of your icon in android reference website it is stated that
Set the small icon to use in the notification layouts. Different classes of devices may return different sizes.
Also see this guiadeline for Keyline Shapes
I tested on android 9,10,11. It's working fine.
In android studio, select image asset -> click icon type -> click Notification icons like this notification icon creation in android studio or create vector asset.both worked.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scrolling)
sendNotification("Hello","thinking of refering friend?",intent);
}
private fun sendNotification(title: String?, message: String?, intent: Intent) {
val pendingIntent = PendingIntent.getActivity(
this,
0 /* Request code */,
intent,
PendingIntent.FLAG_ONE_SHOT
)
// With the default notification channel id the heads up notification wasn't displayed
val channelId = getString(R.string.heads_up_notification_channel_id)
val notificationBuilder =
NotificationCompat.Builder(this, channelId).setSmallIcon(R.drawable.abcd)
.setAutoCancel(true)
.setColorized(true)
.setColor(ContextCompat.getColor(this, R.color.color_orange))
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent)
if (title != null) {
notificationBuilder.setContentTitle(title)
}
if (message != null) {
notificationBuilder.setContentText(message).setStyle(
NotificationCompat.BigTextStyle()
.bigText(message)
)
}
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,
"Test",
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(Random.nextInt()/* ID of notification */, notificationBuilder.build())
}
}
let me know .
In my application I have several activities and one is chat. In this screen I have the ID of who is chatting with me and every time I send a message a push notification is sent with the message and the id of the person with whom I am chatting. While I'm chatting with this person I need to block notifications from them and only receive them if I don't have an open chat with that person. How do I do this? I'm using Firebase as a backend.
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
remoteMessage.notification?.let { notification ->
val data = remoteMessage.data
val type = data["type"] // chat message,like etc
val id = data["id"] //userId
val notificationChannelId = getString(R.string.default_notification_channel_id)
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val intent = setIntent(remoteMessage).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(notificationChannelId, CHANNEL_SPEEACHT, NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(notificationChannel)
}
val notificationBuilder = NotificationCompat.Builder(this, notificationChannelId)
.setContentTitle(notification.title ?: "")
.setContentText(notification.body ?: "")
.setSmallIcon(R.drawable.ic_stat)
.setSound(soundUri)
.setColor(ContextCompat.getColor(applicationContext, R.color.colorNotification))
.setAutoCancel(true)
.setContentIntent(pendingIntent)
notificationManager.notify(0, notificationBuilder.build())
}
}
I think this is not firebase-cloud-messaging related, because firebase-cloud-messaging is just a message channel, so you should do it in your own bussiness code.
A suggested way is that you can make a condition. if the activity is visable and the userid you received in onMessageReceived is the same as the userid you are chatting with, then you should not create your own notification in onMessageReceived function.
Is there a way to set channels on Android Oreo when using NotificationManagerCompat and NotificationCompat?
Since NotificationManagerCompat is just a wrapper class that makes life easier, you can create the channels normally:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = getString(R.string.channel_title)
val description = getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(CHANNEL_ID, name, importance)
mChannel.description = description
mChannel.enableLights(true)
mChannel.lightColor = Color.parseColor("#5B3C88")
mChannel.enableVibration(true)
mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
val manager = (context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
manager.createNotificationChannel(mChannel)
}
And then use the NotificationManagerCompat when you post the notifications, but don't forget to construct the notification using the new constructor:
NotificationCompat.Builder(context, CHANNEL_ID)
Using NotificationManagerCompat with AndroidX is the recommended way.
NotificationManagerCompat now supports Notification channels. The new version Added Notification channels methods to NotificationManagerCompat so developers can use only NotificationManagerCompat when working with notifications.
For Java, include the following in your build.gradle file
implementation 'androidx.core:core:1.2.0'
For Kotlin, include the following instead of the above dependency in your build.gradle file
implementation 'androidx.core:core-ktx:1.2.0'
To display a notificaiton, you will have to do the following
Create and register notification channel.
Create a notification.
Show the notification
The snippets below are in Kotlin, but you can also use Java if you want.
1. Create and register a notification channel.
Notification channels provide a common visual and auditory experience for notifications of a similar type. Since their introduction in API 26, you are now required to set a channel for a notification, otherwise they will not display on newer versions of Android.
So define a helper method as shown below to create a notification channel for you.
//define your channel id
val CHANNEL_ID = "com.yourpackagename.your_channel_id"
//create notification channel for android Oreo and above devices.
if (Build.VERSION.SDK_INT >= 26) {
val channel = NotificationChannel(CHANNEL_ID , "Your channel name", NotificationManager.IMPORTANCE_DEFAULT)
NotificationManagerCompat.from(this).createNotificationChannel(channel)
}
2. Create a notification.
Use the NotificationCompat.Builder to create a Notificaiton. Please note that the CHANNEL_ID is passed to the builder.
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Much longer text that cannot fit one line...")
.setStyle(NotificationCompat.BigTextStyle()
.bigText("Much longer text that cannot fit one line..."))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
3. Show the notification
To make the notification appear, call NotificationManagerCompat.notify(), passing it a unique ID for the notification and the result of NotificationCompat.Builder.build()
NotificationManagerCompat.from(this).notify(notificationId, builder.build())
That's all :)
I usually use this class to manage notification channels:
class NotificationManager(private val context: Context) {
companion object {
private val CHANNEL_ID = "YOUR_CHANNEL_ID"
private val CHANNEL_NAME = "Your human readable notification channel name"
private val CHANNEL_DESCRIPTION = "description"
}
#RequiresApi(Build.VERSION_CODES.O)
fun getMainNotificationId(): String {
return CHANNEL_ID
}
#RequiresApi(Build.VERSION_CODES.O)
fun createMainNotificationChannel() {
val id = CHANNEL_ID
val name = CHANNEL_NAME
val description = CHANNEL_DESCRIPTION
val importance = android.app.NotificationManager.IMPORTANCE_LOW
val mChannel = NotificationChannel(id, name, importance)
mChannel.description = description
mChannel.enableLights(true)
mChannel.lightColor = Color.RED
mChannel.enableVibration(true)
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
mNotificationManager.createNotificationChannel(mChannel)
}
}
Then you can use util like this
fun createNotificationCompatBuilder(context: Context): NotificationCompat.Builder {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return NotificationCompat.Builder(context, NotificationManager(context).mainNotificationId)
} else {
return NotificationCompat.Builder(context)
}
}
This way you can use it in any place of your application with signature just like you have used before and you can easily change it in case of future changes.