FCMDebug logoFCMDebug

FCM with Android

Integrate Firebase Cloud Messaging in your Android app using Kotlin.

Requires Android 6.0 (API level 23) or higher with Google Play services installed.

Setup

1. Add Firebase to Your Project

Add the Google services plugin to your project-level build.gradle.kts:

kotlin
plugins {
    id("com.google.gms.google-services") version "4.4.4" apply false
}

Add to your app-level build.gradle.kts:

kotlin
plugins {
    id("com.google.gms.google-services")
}

dependencies {
    implementation(platform("com.google.firebase:firebase-bom:34.11.0"))
    implementation("com.google.firebase:firebase-messaging")
}

Note: Starting with BoM v32.5.0, Kotlin developers should use the main modules (e.g. firebase-messaging) instead of KTX variants (e.g. firebase-messaging-ktx). The main modules now include Kotlin extensions directly. KTX libraries were removed from the BoM in v34.0.0 (July 2025).

2. Get the Device Token

kotlin
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val token = task.result
        Log.d("FCM", "Token: $token")
    }
}

3. Create a Messaging Service

kotlin
class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        Log.d("FCM", "New token: $token")
        // Send token to your server
    }

    override fun onMessageReceived(message: RemoteMessage) {
        Log.d("FCM", "From: ${message.from}")

        // Notification payload
        message.notification?.let {
            Log.d("FCM", "Title: ${it.title}")
            Log.d("FCM", "Body: ${it.body}")
        }

        // Data payload
        if (message.data.isNotEmpty()) {
            Log.d("FCM", "Data: ${message.data}")
        }
    }
}

4. Register the Service

Add to your AndroidManifest.xml:

xml
<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Notification Channels (Android 8+)

kotlin
private fun createNotificationChannel() {
    val channel = NotificationChannel(
        "default_channel",
        "Default",
        NotificationManager.IMPORTANCE_HIGH
    ).apply {
        description = "Default notification channel"
    }
    val manager = getSystemService(NotificationManager::class.java)
    manager.createNotificationChannel(channel)
}

Important: Create your notification channel before sending any notifications, especially on Android 13+. If your app's first notification channel is created while the app is in the background (e.g. by the FCM SDK), Android won't display the notification and won't prompt the user for permission until the next app launch — and those notifications will be lost.

And in the Android-specific config, use the android.notification.channel_id field to target the channel.

Notification Permission (Android 13+)

Android 13 (API level 33) introduced a runtime permission for showing notifications. The FCM SDK (v23.0.6+) includes POST_NOTIFICATIONS in the manifest automatically, but your app must also request it at runtime:

kotlin
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK can now post notifications
    } else {
        // Inform user that notifications are disabled
    }
}

private fun askNotificationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        when {
            ContextCompat.checkSelfPermission(
                this, Manifest.permission.POST_NOTIFICATIONS
            ) == PackageManager.PERMISSION_GRANTED -> {
                // Permission already granted
            }
            shouldShowRequestPermissionRationale(
                Manifest.permission.POST_NOTIFICATIONS
            ) -> {
                // Show UI explaining why notifications matter, then request
                requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
            }
            else -> {
                requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
            }
        }
    }
}

Important: If you target Android 12L (API 32) or lower, Android will auto-prompt for permission when your app creates its first notification channel — but only if the app is in the foreground at that moment. Create your channels early to avoid missed notifications.

Topic Subscription

kotlin
FirebaseMessaging.getInstance().subscribeToTopic("news")
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d("FCM", "Subscribed to news")
        }
    }

Testing

  1. Run your app and copy the FCM token from Logcat

  2. Open the FCM Tester

  3. Paste service account JSON and the device token

  4. Send a notification

Common Issues

IssueFix
google-services.json not foundDownload from Firebase Console → Project settings → Your apps
No notification on Android 13+Request POST_NOTIFICATIONS permission at runtime and create a notification channel on app launch
Notification not showing in foregroundThe FCM SDK does not auto-display notifications when the app is in foreground — handle it manually in onMessageReceived
Notification not showing (background)Check that the notification channel exists and its importance is set to HIGH
Token changes unexpectedlyAlways handle onNewToken() and sync the new token to your server

Related

Was this page helpful?