'android - Tapping notifications in the foreground does not respond with Firebase Cloud Messaging

I am using Firebase Cloud Messaging to implement notifications in android app. I'm new to android. Please help me.

Problem

When I receive a notification in the foreground state, there is unexpected movement.

  • Expectation: Nothing is done at the timing when the notification is received. I want to process the notification when I tap it.
  • Actual: BroadcastReceiver's onReceive is called at the timing when the notification is received. It doesn't respond when I tap it ("test onCreate" is not displayed in logcat).

Note: This app is entirely operated by a fragment on MainActivity.

Files

PushNotificationListenerService.kt

class PushNotificationListenerService: FirebaseMessagingService() {
    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)
        
        val channelId = message.notification?.channelId.toString()
        val title: String = message.notification?.title.toString()
        val text: String = message.notification?.body.toString()

        sendNotification(
            title,
            text,
            channelId
        )

        var broadcast = Intent()
        broadcast.action = "FCM_RECEIVE_FOREGROUND"

        sendBroadcast(broadcast)
    }

    private fun sendNotification(
        title: String,
        text: String,
        receivedChannelId: String,
    ) {
        val intent = Intent(this, HomeFragment::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

        val pendingIntent =
            PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
                .apply {
                    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
                }

        val notificationBuilder = NotificationCompat.Builder(this, receivedChannelId)
            .setContentTitle(title)
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_menu_logo)
            .setContentIntent(pendingIntent)
            .setPriority(PRIORITY_MAX)
            .setCategory(CATEGORY_CALL)
            .setAutoCancel(true)
            .setSound(null)
            .setVibrate(null)

        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val uuid = UUID.randomUUID().hashCode()
        notificationManager.notify(uuid, notificationBuilder.build())

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationBuilder.setChannelId(receivedChannelId)
        }
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var navController: NavController
    private var mReceiver: BroadcastReceiver? = null
    private val mIntentFilter = IntentFilter("FCM_RECEIVE_FOREGROUND")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Timber.d("test onCreate")

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.lifecycleOwner = this

        mReceiver = (object: BroadcastReceiver() {
            override fun onReceive(p0: Context?, p1: Intent?) {
                Timber.d("test onReceive called")
                if (p1 == null) { return }
            }
        })

        setupChannels()
    }

    override fun onResume() {
        super.onResume()
        registerReceiver(mReceiver, mIntentFilter)
    }

    override fun onPause() {
        if (mReceiver != null) {
            unregisterReceiver(mReceiver)
            mReceiver = null
        }
        super.onPause()
    }

    private fun setupChannels() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val attribute = AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .build()
            var uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
            
            val channel = NotificationChannel(
                "channelId",
                "channelName",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                vibrationPattern = createVibrate()
                lightColor = Color.BLUE
                lockscreenVisibility = Notification.VISIBILITY_PUBLIC
                setSound(uri, attribute)
            }
            
            manager.createNotificationChannel(channel)
        }
    }
}

payload on notification from Firebase Cloud Messaging

const fcmTokenMessage: admin.messaging.TokenMessage = {
  android: {
    data: {},
    notification: {
      body: "message",
      title: "title",
      defaultSound: true,
      channelId: "channelId",
      sound: 'default',
      priority: 'high',
      notificationCount: fcmPushData.notificationCount
    }
  },
  token: fcmPushData.fcmPushToken
};

Versions

build.gradle

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32"
        classpath "org.jetbrains.kotlin:kotlin-serialization:1.4.32"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
        classpath 'com.google.gms:google-services:4.3.8'

        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

That's all. I apologize for the inconvenience, and thank you for your cooperation.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source