c0dehunter
c0dehunter

Reputation: 6160

How to let FCM display notification even when app is in foreground?

Let FCM handle notifications on device, if it's not a data message.

How can I force Android to show notification using FCM, even when app is in foreground? I don't want to build my own notification.

I am sending two types of messages to my app: data message and normal notification message. Data messages are handled in onMessageReceived(), no matter if the App is in background or foreground or killed which is OK. But now I am also sending normal notification messages through Firebase Console, and they are automatically displayed when app is in background but when app is in foreground, onMessageReceived() is called. Here, I would need to somehow tell FCM to show the contents without me having to build the notification.

I tried with:

@Override public void onMessageReceived(RemoteMessage remoteMessage) {
        if(remoteMessage.getData() == null || !remoteMessage.getData().containsKey("specificKey")) {
            // notification msg, let FCM handle it
            super.onMessageReceived(remoteMessage); // this is not working - I want FCM to show notification the same as if the app was in background. 
            return;
        } else {
          // data message, I'm handling it on my own and showing a custom notification, working fine and well
        }
}

But this is my own handling via code and I want FCM to do that somehow. How can I do that?

Upvotes: 7

Views: 5843

Answers (2)

Nitin Gurbani
Nitin Gurbani

Reputation: 1240

In this, the else part needs to be handled by you to show a custom notification as follows:

class FCMMessagingService: FirebaseMessagingService() {
    var dataMap: Map<String, String>? = null
    var body: String = ""
    var title: String = ""

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

        dataMap = remoteMessage?.data
        Log.d("Data Map", dataMap.toString())

        try {
            val jsonObject = JSONObject(dataMap?.get("data")!!)
            val contentInfo = jsonObject.get("contentInfo") as JSONObject

            val time = contentInfo.getString("time")
            var message = jsonObject.getString("message")
            message = message.replace("<time>", Utils.getTimeFromTimestamp(time.toLong(), true))
            body = message
        } catch (e:JSONException) {
            e.printStackTrace()
        }

        title = dataMap?.get("title")!!
        if(Foreground.get().foreground) {
            sendBroadCast(title , body)
        } else {
            createNotification(title, body)
        }
    }

    private fun createNotification(title: String, body: String) {
        val intent = Intent(this, DashBoardActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

        val pendingIntent = PendingIntent.getActivity(this, Calendar.getInstance().timeInMillis.toInt(), intent,
                PendingIntent.FLAG_ONE_SHOT)

        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notification = NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.noti)
                .setContentTitle(title)
                .setContentText(body)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent)
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            notification.color = resources.getColor(R.color.toolBarColor)
        }

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(Calendar.getInstance().timeInMillis.toInt(), notification.build())
    }

    private fun sendBroadCast(title: String, body: String) {
        val broadCastIntent = Intent(Constant.NOTIFICATION)
        broadCastIntent.putExtra("title", title)
        broadCastIntent.putExtra("body", body)
        LocalBroadcastManager.getInstance(this).sendBroadcast(broadCastIntent)
        // val intent = Intent(this, DashBoardActivity::class.java)
        // intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
    }
}

I believe you will have to do it this way only as FCM won't handle it anyhow for you. I hope, this helps you.

Upvotes: 0

Frank van Puffelen
Frank van Puffelen

Reputation: 600061

When the app is not in the foreground, notification messages are handled by the system. This is by definition and there is no way to change the behavior.

If you want to control what is displayed while the app is not in the foreground, you will have to send a data message.

Upvotes: 2

Related Questions