Push messages with FCM

Background work and notifications Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Predict the output

The app is in the background. The server sends a message with both a notification and a data payload. What happens?

class PushService : FirebaseMessagingService() {
    override fun onMessageReceived(message: RemoteMessage) {
        log("received ${message.data}")
    }
    override fun onNewToken(token: String) {
        log("new token")
    }
}
Options
Hint 1 of 1

Who handles notification payloads when the app is backgrounded?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A The system shows the notification; onMessageReceived isn't called, and data arrives in the launch intent on tap

Correct. In the background, notification payloads are handled by the system tray.

Why not the others?
  • B onMessageReceived runs and the app must build the notification. That's what happens for data-only messages, or in the foreground.
  • C Nothing is shown until the app is opened. The system shows notification messages for you.
  • D Both the system and onMessageReceived show a notification. Only one path handles it.

30-second answer

The app gets a registration token from FCM and sends it to your server, which sends messages to that token through FCM. Notification messages are shown by the system automatically when the app is in the background. Data messages always go to onMessageReceived in your FirebaseMessagingService, so you control display and logic. Tokens can change, so handle onNewToken.

Practise saying it · 35 s. No recording, just a timer

Explain FCM message types.

Say your answer out loud, then check which of these points you covered:

  • Token registration with your server
  • Notification messages shown by the system in background
  • Data messages go to onMessageReceived
  • Handle onNewToken
  • Keep the handler short

Deep dive

High priority is for messages that show a notification right away; abusing it gets messages deprioritised.

Keep onMessageReceived short; enqueue WorkManager for anything slow.

Mixed messages: in the background, the notification part is shown and the data goes to the launch intent when tapped.

Delete the token and tell your server on logout.

Common mistakes

  • Expecting onMessageReceived to run for notification messages in the background.
  • Doing network calls directly in onMessageReceived.
  • Never updating the server when the token changes.

Senior take & follow-ups

Get the background behaviour of notification vs data messages right; it's the common trap.

Follow-up questions

Think of your answer first, then open the hint.

  1. When does onNewToken run?

    Show hint

    On first start, after reinstall, after data clear and on token rotation.

  2. Why might high-priority messages be downgraded?

    Show hint

    If they don't result in a user-visible notification.

Similar on iOS: Routing a notification tap on cold start APNs delivers to the system the same way; routing a tap on a cold start is the shared problem.

Suggest a fix if something here is wrong or out of date.