1

I have a problem with my Android notifications (sent via FCM). Let me explain.

I can send "classic" notifications which are displayed in the notification bar. I can send notifications with personalized data but they are not displayed in the notification bar.

However, I can't do both. Currently, the payload I send looks like this:

{
   "to":"token",
   "message":{
      "notification":{
         "body":"Body",
         "title":"Title"
      }
   },
   "data":{
      "id":2543,
      "type":"EVENT"
      "title":"Title"
      "body":"Body"
   }
}

It does send the data notification. But it doesn't display on the phone. In my service I have my onMessageReceived function with, among other things, this:

val id = remoteMessage.data["id"]
val type = remoteMessage.data["type"]

As long as my notification goes to data mode, I can get these values.

So, I think there is a concept between display notifications and data notifications that I don't understand.

I used this link: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

And when I put my data array in message the notification does not arrive.

If you have a clue, I'm interested. The basic idea is that when the user clicks on the notification (which contains the title of an event), the application opens the activity that goes well with the details of the event.

Thanks for your help

[EDIT] This is my onMessageReceived(remoteMessage: RemoteMessage) function in my service that extends FirebaseMessagingService

override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        val intent:Intent?

        val id = remoteMessage.data["id"]
        val type = remoteMessage.data["type"]
        val title = remoteMessage.data["title"]
        val body = remoteMessage.data["body"]

        Log.i("YANN", "RemoteMessage Data : " + remoteMessage.data)
        Log.i("YANN", "Id : $id")
        Log.i("YANN", "Type : $type")
        Log.i("YANN", "Title : $title")
        Log.i("YANN", "Body : $body")

        when (type) {
            "NOTIFICATION" -> {
                // TODO : Load the NotificationFragment
                intent = Intent(this, MainActivity::class.java)
            }
            "POST" -> {
                var post:Post = Post(0, "", "", "", "", "")
                
                // DO SOMETHING TO RETRIVE THE POST
                intent = Intent(this, PostActivity::class.java)
                intent.putExtra("post", post)
            }
            "EVENT" -> {
                var event = Event(0, "", "", "", "", "", "", "")
                
                // DO SOMETHING TO RETRIEVE THE EVENT
                intent = Intent(this, EventActivity::class.java)
                intent.putExtra("event", event)
            }
            else ->  {
                intent = Intent(this, MainActivity::class.java)
            }
        }
        
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
        val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)

        val notification = NotificationCompat.Builder(this, resources.getString(R.string.default_notification_channel_id))
            .setSmallIcon(R.drawable.ic_dashboard_black_24dp)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setSound(soundUri)
            .setContentIntent(pendingIntent)

        NotificationManagerCompat.from(this).notify(1, notification.build())
    }

[EDIT2] There is the new NotificationBuilder

val builder: NotificationCompat.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val importance = NotificationManager.IMPORTANCE_DEFAULT
    val notificationChannel = NotificationChannel(resources.getString(R.string.default_notification_channel_id), resources.getString(R.string.default_notification_channel_id), importance)
    val notificationManager:NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.createNotificationChannel(notificationChannel)
    NotificationCompat.Builder(this, notificationChannel.id)
} else {
    NotificationCompat.Builder(this)
}

builder.setSmallIcon(R.drawable.ic_dashboard_black_24dp)
builder.setContentTitle(title)
builder.setContentText(body)
builder.setAutoCancel(true)
builder.setSound(soundUri)
builder.setContentIntent(pendingIntent)


val notificationID = (0..999999999).random()
NotificationManagerCompat.from(this).notify(notificationID, builder.build())
Yann
  • 13
  • 5

1 Answers1

2

dealing with push notifications on Android is a bit of a pain indeed. The easiest way to fix your problem is to create the notification yourself.

Somewhere in your code there must be a Service class that extends FirebaseMessagingService which you've declared in your AndroidManifest.xml. It has an onMessageReceived(message: RemoteMessage) method.

You can get the content of the message like so

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)

        val remoteNotification = message.notification ?: return
        val title : String = remoteNotification.title
        val body : String = remoteNotification.body

Then you just need to display it yourself by creating the notification, you can find more information about creating a notification here:

https://developer.android.com/training/notify-user/build-notification

EDIT: On the latests versions of Android, from Oreo, you need to specify the channel, which you did. But you forgot to create the channel. Also make sure you support older versions of Android. Like so:


var builder: NotificationCompat.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val notificationChannel = NotificationChannel("mainChannelId", "Main", importance)
            notificationManager.createNotificationChannel(notificationChannel)
            NotificationCompat.Builder(applicationContext, notificationChannel.id)
        } else {
            NotificationCompat.Builder(applicationContext)
        }
Benoit TH
  • 362
  • 1
  • 7
  • Hi, thanks for helping. I'm already using a custom service that extends `FirebaseMessagingService`. I'll edit my orginal post to show it to you ;) – Yann Apr 21 '21 at 07:43
  • And you're saying this `onMessageReceived ` function doesn't get called? It should only get called when the app is in the foreground. https://stackoverflow.com/questions/37358462/firebase-onmessagereceived-not-called-when-app-in-background – Benoit TH Apr 21 '21 at 08:13
  • This function is called. Logs are good with correct data. But notification is not displayed. And I don’t understand why ... – Yann Apr 21 '21 at 08:19
  • I have edited my answer, let me know if this works – Benoit TH Apr 21 '21 at 08:26
  • Ok not sure to understand the `notificationManager.createNotification` line. You've not declared it. I added it and it seems to work. I'll edit my post again. Thanks ! – Yann Apr 21 '21 at 08:45