androidfirebasekotlinnotificationsfirebase-cloud-messaging

Can't get correct Icon or Intent when sending notification through Firebase Cloud Messaging android


I'm using Firebase Cloud Messaging to send notifications to users about updates in my Android app. Notifications work fine when the app is in the foreground, but when the app is in the background or closed, I experience two issues:

The notification icon is just a blank circle instead of the specified drawable (R.drawable.notification_icon). Clicking the notification opens the app instead of the intended URL (which should open a webpage). I think this might be related to the context, but I’ve already tried using applicationContext, and the issue still happens.

My Implementation:

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        // Get the notification data
        val notification = remoteMessage.notification

        val notificationIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/georgeclensy/escape"))
        if (notification != null) {
            notification.title?.let { title ->
                notification.body?.let { body ->
                    sendNotification(
                        this, title, body, "updates", "Updates", notificationIntent
                    )
                }
            }
        }
    }

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d("FCM", "New token: $token")
    }
}

fun sendNotification(context: Context, title: String, message: String, channelID: String, channelName: String, intent: Intent) {
    val notificationId = 1

    // Create a notification channel (only needed for Android 8.0+)
    val channel = NotificationChannel(
        channelID,
        channelName,
        NotificationManager.IMPORTANCE_DEFAULT
    ).apply {
        description = channelName
    }

    val pendingIntent = PendingIntent.getActivity(
        context,
        0,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

    val notificationManager: NotificationManager =
        context.getSystemService(NotificationManager::class.java)
    notificationManager.createNotificationChannel(channel)

    // Build the notification
    val notification = NotificationCompat.Builder(context, channelID)
        .setSmallIcon(R.drawable.notification_icon) // This is showing as a blank circle
        .setContentTitle(title)
        .setContentText(message)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setAutoCancel(true)
        .setContentIntent(pendingIntent)
        .build()

    with(NotificationManagerCompat.from(context)) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
            return
        }
        notify(notificationId, notification)
    }
}

Solution

  • The problem is likely that you're sending a "notification message" instead of a "data message". Firebase's docs say that notification messages will only call your callback if your app is running, but otherwise will be displayed by the FCM SDK itself. Whereas data messages always go via your callback:

    Firebase Cloud Messaging docs snippet https://firebase.google.com/docs/cloud-messaging/concept-options

    You'll need to change how you're sending the notification from the Firebase console to make it a data message, and change your app code to get its data from remoteMessage.data instead of removeMessage.notification