'Handle FCM notifications with navigation component

I'm developing an Android app with navigation component, I added the deeplink to the navigation

<fragment
    android:id="@+id/searchFragment"
    android:label="@string/navigation_search_label"
    tools:layout="@layout/fragment_search">
    <deepLink
        android:id="@+id/deepLink2"
        app:uri="http://example/search" />
</fragment>

And added the navigation file to AndroidManifest :

        <nav-graph android:value="@navigation/nav_graph" />

But I can't find how to send the uri in FCM and how to handle it so that the user can be redirected to that fragment. Anyone have experience on this?



Solution 1:[1]

You don't need to set uri in FCM, just send required data in fcm message and construct uri in your application.

Here's what you need to send from backend (remember to send data)

val data = mapOf("someId" to "12345")

val notification = Notification.builder()
    .setTitle(title)
    .setBody(body)
    .build()

val message = Message.builder()
    .setToken(token)
    .setNotification(notification)
    .putAllData(data)
    .build()

firebaseMessaging.send(message)

Then, use below code in your (android) messaging service to receive (and construct) notification in both foregroud/backgruoud app scenario

class YourFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        remoteMessage.notification?.let {
            val intent = Intent(this, MainActivity::class.java).apply {
                remoteMessage.data.forEach { (k, v) ->
                    putExtra(k, v)
                }
            }

            // Create PendingIntent with backstack maintained
            val pendingIntent = TaskStackBuilder.create(this).run {
                addNextIntentWithParentStack(intent)
                getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
            }

            val builder = NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
                    .setSmallIcon(R.drawable.your_logo)
                    .setContentTitle(it.title)
                    .setContentText(it.body)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setContentIntent(pendingIntent)
                    .setDefaults(Notification.DEFAULT_SOUND)
                    .setAutoCancel(true)

            with(NotificationManagerCompat.from(this)) {
                notify(remoteMessage.messageId?.toIntOrNull() ?: 1, builder.build())
            }
        }
    }
}

And finally, in your MainActivity

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // other stuff...

        intent.extras?.let {
            // Construct url (or multiple url based on requirement)
            val url = "$YOUR_WEBSITE_NAME/user/${intent.getStringExtra("someId")}"
            val intent = Intent(
                Intent.ACTION_VIEW,
                url.toUri(),
                this,
                MainActivity::class.java
            )
            startActivity(intent)
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Annon