Firebase Cloud Messaging for push notifications

Alex Chen Jan 2026
2 tabs
package com.example.myapp.services

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import com.example.myapp.R
import com.example.myapp.ui.MainActivity
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

@AndroidEntryPoint
class MyFirebaseMessagingService : FirebaseMessagingService() {

    @Inject
    lateinit var tokenManager: TokenManager

    override fun onNewToken(token: String) {
        super.onNewToken(token)

        // Send token to backend server
        tokenManager.saveFcmToken(token)
        // TODO: Send to server via API
    }

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

        // Handle data payload
        message.data.isNotEmpty().let {
            handleDataMessage(message.data)
        }

        // Handle notification payload
        message.notification?.let {
            sendNotification(
                title = it.title ?: "New Message",
                body = it.body ?: "",
                data = message.data
            )
        }
    }

    private fun handleDataMessage(data: Map<String, String>) {
        val type = data["type"]
        when (type) {
            "new_post" -> {
                val postId = data["post_id"]?.toIntOrNull()
                postId?.let {
                    sendNotification(
                        title = "New Post",
                        body = data["title"] ?: "",
                        data = mapOf("post_id" to it.toString())
                    )
                }
            }
            "new_comment" -> {
                // Handle comment notification
            }
            "new_like" -> {
                // Handle like notification
            }
        }
    }

    private fun sendNotification(
        title: String,
        body: String,
        data: Map<String, String> = emptyMap()
    ) {
        val intent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            data["post_id"]?.let {
                putExtra("post_id", it.toInt())
            }
        }

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

        val channelId = "default_channel"
        createNotificationChannel(channelId)

        val notification = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build()

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
            as NotificationManager
        notificationManager.notify(System.currentTimeMillis().toInt(), notification)
    }

    private fun createNotificationChannel(channelId: String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "Default Notifications",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                description = "Notifications for new posts and comments"
            }

            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
                as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}
2 files · kotlin Explain with highlit

Firebase Cloud Messaging (FCM) delivers push notifications across platforms. I extend FirebaseMessagingService and override onMessageReceived() to handle incoming messages. Device tokens obtained via FirebaseMessaging.getInstance().token register with backend. Notification channels define priority and behavior on Android 8+. Data messages execute app logic, while notification messages show system notifications. RemoteMessage contains data and notification payloads. Topics enable broadcast messaging with subscribeToTopic(). Background and foreground messages require different handling. Analytics track delivery and engagement. FCM ensures reliable, real-time communication for user engagement and updates.