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?
CodePudding user response:
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)
}
}
}
CodePudding user response:
One has to set a click_action
for the notification... else there won't be any URL Intent
.
In Android Studio run configurations one can select "Launch Options" > "Launch" > "URL".
This effectively simulates clicking such a link - which is quite useful for testing deep-links.
An IntentFilter
needs to be registered in the AndroidManifest.xml
, to filter the URL Intent
:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
<data android:host="acme.com"/>
</intent-filter>
<nav-graph
android:value="@navigation/nav_graph"/>
Also make sure to have the corresponding .well-known/assetlinks.json
hosted on that domain.
Use deepLink
and argument
for navigation:
<deepLink
app:uri="https://acme.com/search?term={searchTerm}"/>
<argument
android:name="searchTerm"
app:argType="string"/>