Skip to content

Firebase FCM Token — Complete Guide

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about Firebase FCM Token. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Your FCM token is empty, or you send a notification to the stored token and it doesn't arrive because the token was refreshed.

Wrong Approach ❌

// Getting token on main thread — may be delayed
val token = FirebaseMessaging.getInstance().token // Not yet available!
// Storing token once at app startup
override fun onCreate() {
    super.onCreate()
    FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
        val token = task.result
        saveTokenToServer(token) // Token stored once — never updated!
    }
}

Output: Token is null or stale. Notifications fail silently.

Right Approach ✅

// FCM Service to handle token
class MyFcmService : FirebaseMessagingService() {

    // Called when a new token is generated (initial + refresh)
    override fun onNewToken(token: String) {
        super.onNewToken(token)
        sendTokenToServer(token)
        saveTokenLocally(token)
    }

    private fun sendTokenToServer(token: String) {
        // Use coroutine for network call
        CoroutineScope(Dispatchers.IO).launch {
            try {
                api.registerDeviceToken(token)
            } catch (e: Exception) {
                // Retry on next app launch
                scheduleTokenRetry(token)
            }
        }
    }
}

// In Application class — retrieve existing token
class App : Application() {
    override fun onCreate() {
        super.onCreate()

        // Retrieve current token (may be null if not yet generated)
        FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val token = task.result
                Log.d("FCM", "Token: $token")
            }
        }

        // Alternative: blocking suspend call in a coroutine
        CoroutineScope(Dispatchers.IO).launch {
            val token = FirebaseMessaging.getInstance().token.await()
            Log.d("FCM", "Token: $token")
        }
    }
}

// Special handling for Firebase on Android
// Ensure google-services.json is in app/ folder and FCM dependency is added

Output: Token always available and synced to server.

Prevention

  • Implement FirebaseMessagingService.onNewToken() for token refresh.
  • Store token locally and sync to server on every change.
  • Use .await() from kotlinx.coroutines.tasks.await for clean Coroutine usage.
  • Retry token upload if server is unreachable.

Common Mistakes with Firebase fcm token

  1. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
  2. Using return to exit a function early instead of wrapping a pure value in the monad
  3. Mixing let bindings with <- bindings in do notation, producing type errors

These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### When is onNewToken called?

On initial app install, when the token is refreshed (every ~6 months or on security change), when the app is restored after device restore, and when the FCM SDK version changes.

### Why is my token null at app startup?

The FCM SDK initializes asynchronously. The token may not be available immediately. Use addOnCompleteListener or await() inside a Coroutine.

### Can I manually force a token refresh?

Yes. Call FirebaseMessaging.getInstance().deleteToken() followed by getting the token again. This generates a new token and invalidates the old one.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro