Skip to content

Cold start: buffer notification click payload; recognize google.message_id; explicit launch extra #165

Description

@alexvarboffin

Problem

When the user taps an FCM notification while the app process is killed, our launcher Activity starts with push data in Intent.extras, but NotifierManager.Listener.onNotificationClicked is often not called because we register listeners in Compose (LaunchedEffect) after MainActivity.onCreate().

In NotifierManagerImpl.onNotificationClicked, if listeners.isEmpty() the event is only logged and dropped — there is no pending/buffered payload API.

Legacy behavior (previous native WebView app)

We detected a notification launch in Activity.onCreate with:

intent.getStringExtra("google.message_id") != null

Then we read FCM data keys: msg.id, msg.title, msg.body, msg.user, persisted the message, and navigated to our messages screen (initialRoute).

Current KMPNotifier behavior (observed)

  • NotifierManager.onCreateOrOnNewIntent(intent) must be called in launcher Activity onCreate / onNewIntent — we do this.
  • Click detection uses ACTION_NOTIFICATION_CLICK or google.sent_time (KEY_ANDROID_FIREBASE_NOTIFICATION), not google.message_id.
  • AndroidNotifier.getPendingIntent() sets ACTION_NOTIFICATION_CLICK and copies payloadData into extras; launch intent is PackageManager.getLaunchIntentForPackage().
  • System-shown FCM tray notifications (app killed) often deliver Firebase extras including google.message_id, which our legacy app relied on.
  • The library does not open any screen — only callbacks. That is fine; we need a reliable click payload on cold start.

Expected / requested changes

1. Explicit launch marker on all notification PendingIntents

Add a documented extra on every notification PendingIntent from the library, e.g.:

const val EXTRA_NOTIFICATION_LAUNCH = "com.mmk.kmpnotifier.EXTRA_NOTIFICATION_LAUNCH"
// intent.putExtra(EXTRA_NOTIFICATION_LAUNCH, true)

Use it in isNotificationClicked together with existing markers.

2. Treat google.message_id as a notification-click marker

In NotifierManager.onCreateOrOnNewIntent, include Firebase’s google.message_id in click detection (in addition to ACTION_NOTIFICATION_CLICK and google.sent_time), for compatibility with default FCM tray notifications and legacy apps.

3. Buffer notification-click payload until first listener is registered

Example API:

// NotifierManagerImpl
private var pendingNotificationClick: PayloadData? = null

fun onNotificationClicked(data: PayloadData) {
    if (listeners.isEmpty()) pendingNotificationClick = data
    else listeners.forEach { it.onNotificationClicked(data) }
}

// NotifierManager (public)
fun consumePendingNotificationClick(): PayloadData? =
    pendingNotificationClick.also { pendingNotificationClick = null }

Or deliver the pending click automatically on addListener / setListener.

This helps KMP/Compose apps that cannot register listeners before Activity.onCreate finishes, even if the README recommends registering in Application.onCreate (see also #74).

4. Documentation

  • Document which Intent extras indicate “opened from notification” (EXTRA_NOTIFICATION_LAUNCH, ACTION_NOTIFICATION_CLICK, google.message_id, google.sent_time).
  • Clarify that business keys (msg.id, etc.) are passed through in PayloadData unchanged.
  • Note cold start: onCreate + notification extras vs warm start: onNewIntent.

What we will do on our side

We will move NotifierManager.addListener to Application.onCreate (as recommended). Items (2) and (3) would still improve FCM tray compatibility and cold start for Compose/KMP consumers.

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions