Search code examples
androidfirebasefirebase-cloud-messagingandroid-notificationsfirebase-notifications

Notification works in Activity but not in Service


I am trying to integrate Firebase Cloud Messages into my app. The code I used in the showNotification function is from the Android User Interface Samples. I tried it in the Activity and it worked but am not sure why it's not working in the service. The println is showing the function is getting called and values are coming as expected. Is there anything am missing from the function?

class MessagingService : FirebaseMessagingService() {

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        if (remoteMessage.data.isNotEmpty()) {
            val message = Gson().fromJson(remoteMessage.data.toString(), Message.Res::class.java).payload!!
            showNotification(message.title, message.body, message.count)
        }
    }

    private fun showNotification(title: String?, body: String?, count: Int = 0) {
        
        println("_print::showNotification(title:$title, body:$body, count:$count)")

        val mainPendingIntent = PendingIntent.getActivity(
            applicationContext, BuildConfig.REQUEST_CODE,
            Intent(applicationContext, MainActivity::class.java),
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        val builder = NotificationCompat.Builder(applicationContext, "channel_email_1")
            .setContentTitle(title)
            .setContentText(body)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_round))
            .setContentIntent(mainPendingIntent)
            .setDefaults(NotificationCompat.DEFAULT_ALL)
            .setColor(ContextCompat.getColor(applicationContext, R.color.primary))
            .setSubText(if (count > 1) "You have $count pending notifications" else title)
            .setCategory(Notification.CATEGORY_EMAIL)
            .setPriority(1)
            .setVisibility(NotificationCompat.VISIBILITY_PRIVATE)

        NotificationManagerCompat.from(applicationContext)
            .notify(BuildConfig.NOTIFICATION_ID, builder.build())
    }
}

Solution

  • Instead of

    val mainPendingIntent = PendingIntent.getActivity(
            applicationContext, BuildConfig.REQUEST_CODE,
            Intent(applicationContext, MainActivity::class.java),
            PendingIntent.FLAG_UPDATE_CURRENT
        )
    
    NotificationManagerCompat.from(applicationContext)
            .notify(BuildConfig.NOTIFICATION_ID, builder.build())
    

    I use:

        val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    
        // Since android Oreo notification channel is needed.
        setupChannels(notificationManager, builder)
    
        // Create pending intent, mention the Activity which needs to be triggered
        // when user clicks on notification.
        val notificationId = Random.nextInt()
        navigateToScreen(builder, notificationId)
    
        val notification = builder.build()
        notificationManager.notify(notificationId, notification)
    }
    
    private fun setupChannels(notificationManager: NotificationManager,
                              builder: NotificationCompat.Builder) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelId = "channel_email_1"
            val channel = NotificationChannel(channelId, "title",
                NotificationManager.IMPORTANCE_DEFAULT).apply {
                description = "body"
                // Add other settings.
                lockscreenVisibility = Notification.VISIBILITY_PUBLIC
                canShowBadge()
                setShowBadge(true)
            }
            notificationManager.createNotificationChannel(channel)
            builder.setChannelId(channelId)
        }
    }
    
    private fun navigateToScreen(builder: NotificationCompat.Builder,
                                 notificationId: Int) {
        val intent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(this, notificationId, intent,
            PendingIntent.FLAG_UPDATE_CURRENT)
        builder.setContentIntent(pendingIntent)
    }