Open Andrew0000 opened 1 month ago
Hi @Andrew0000 ,
Thanks for reporting the issue, one of our team members will take a look and post updates here.
additionally followed the guide on how to enable DEEP linking in your project?
Yes, we use deep links. It works with other notifications. As I understand, the problem happens even before this. The app is launched from the Amplify's notification with android.intent.action.MAIN action and null data in its intent. I logged the intent in my Activity's onCreate() as the earliest point before every in-app navigation. So there is just no data that the app can get a link from.
Have you also followed the steps in our Amplify doc
I believe so. But let me copy the code:
AndroidManifest:
<service
android:name=".PushNotificationService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
App:
Amplify.addPlugin(AWSCognitoAuthPlugin())
Amplify.addPlugin(AWSPinpointAnalyticsPlugin())
Amplify.addPlugin(AWSPinpointPushNotificationsPlugin())
Amplify.configure(applicationContext)
PushNotificationService:
typealias AmplifyKt = com.amplifyframework.kotlin.core.Amplify
import com.amplifyframework.core.Amplify
import com.amplifyframework.notifications.pushnotifications.NotificationContentProvider
import com.amplifyframework.notifications.pushnotifications.NotificationPayload
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import timber.log.Timber
class PushNotificationService : FirebaseMessagingService() {
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
override fun onNewToken(token: String) {
super.onNewToken(token)
Amplify.Notifications.Push.registerDevice(
token,
{ Timber.i("[PushNotificationService][Push][Auth][Amplify] Successfully registered device") },
{ Timber.e(it, "[PushNotificationService][Push][Auth][Amplify] Error registering device") },
)
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
scope.launch {
tryProcessWithPinpoint(remoteMessage)
}
}
private suspend fun tryProcessWithPinpoint(remoteMessage: RemoteMessage) {
val notificationPayload = NotificationPayload(NotificationContentProvider.FCM(remoteMessage.data))
val isAmplifyMessage = Amplify.Notifications.Push.shouldHandleNotification(notificationPayload)
if (isAmplifyMessage) {
AmplifyKt.Notifications.Push.handleNotificationReceived(notificationPayload)
}
}
}
It's a little none of my business, but I'm looking at com.amplifyframework.pushnotifications.pinpoint.PushNotificationsUtils and see nothing related to any link. Where is a link supposed to be put into the Intent?
fun showNotification(
notificationId: Int,
payload: PinpointNotificationPayload,
targetClass: Class<*>?
) {
CoroutineScope(Dispatchers.IO).launch {
val largeImageIcon = payload.imageUrl?.let { downloadImage(it) }
val notificationIntent = Intent(context, payload.targetClass ?: targetClass)
notificationIntent.putExtra("amplifyNotificationPayload", payload)
notificationIntent.putExtra("notificationId", notificationId)
val pendingIntent = PendingIntent.getActivity(
context,
notificationId,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notificationChannel = retrieveNotificationChannel()
val builder = if (isNotificationChannelSupported() && notificationChannel != null) {
NotificationCompat.Builder(context, payload.channelId ?: notificationChannel.id)
} else {
NotificationCompat.Builder(context)
}
builder.apply {
setContentTitle(payload.title)
setContentText(payload.body)
setSmallIcon(R.drawable.ic_launcher_foreground)
setContentIntent(pendingIntent)
setPriority(NotificationCompat.PRIORITY_DEFAULT)
setLargeIcon(largeImageIcon)
setAutoCancel(true)
}
with(NotificationManagerCompat.from(context)) {
notify(notificationId, builder.build())
}
}
}
UPD: I went deeper into AWSPinpointPushNotificationsActivity -> getIntentAction -> PinpointNotificationPayload.fromNotificationPayload ->
action?.get(PushNotificationsConstants.DEEPLINK) != null -> {
// Action is open deeplink
val deepLink = action[PushNotificationsConstants.DEEPLINK]
Intent(Intent.ACTION_VIEW, Uri.parse(deepLink))
}
data[PushNotificationsConstants.PINPOINT_DEEPLINK]?.let {
action.put(PushNotificationsConstants.DEEPLINK, it)
}
const val PINPOINT_DEEPLINK = "$PINPOINT_PREFIX.$DEEPLINK" // pinpoint.deeplink
So maybe I should use pinpoint.deeplink field in my pushes? Just a guess.
Yes, this formatting make deeplinks work:
{
"GCMMessage":{
"data":{
"Action": "DEEP_LINK",
"pinpoint.deeplink": "my url here (deeplink)",
"title": "A title",
"message":"A message"
}
}
}
Could you please confirm that a consumer/developer should use pinpoint.deeplink key in the message in order to make deeplinks work? I literally see no documentation regarding pinpoint.deeplink parameter and I found it only by looking at the Amplify's source code.
Hi @Andrew0000 ,
Glad that you found the solution to it. We will make sure to document these properly so that we can mitigate as many misunderstandings as possible.
Hi @yuhengshs ,
Although my finding works, it would be great if someone could confirm its correctness or provide a code snippet that worked as you mentioned in the first reply. Just to make sure there are no hidden pitfalls in my finding.
@Andrew0000 That looks correct. Amplify is coded to handle templates from using the "Standard message" with "Open a deep link" Action on the Pinpoint console. Using these parameters appears to send as "pinpoint.deeplink".
If you are using the "Raw message" format, then you would still have to follow the same spec as the deep link standard message behavior.
This looks like missing documentation on the Pinpoint site to clarify how the template actions translate into the resulting raw message.
Before opening, please confirm:
Language and Async Model
Kotlin, Kotlin - Coroutines, RxJava
Amplify Categories
Notifications
Gradle script dependencies
Environment information
Please include any relevant guides or documentation you're referencing
https://docs.aws.amazon.com/pinpoint/latest/apireference/apps-application-id-messages.html#apps-application-id-messages-prop-apnsmessage-action
Describe the bug
I'm trying to use deep link in my android app. Seems like Amplify doesn't support it.
What I send from web Pinpoint:
As you can see, I specified Action DEEP_LINK as it's described here: https://docs.aws.amazon.com/pinpoint/latest/apireference/apps-application-id-messages.html#apps-application-id-messages-prop-apnsmessage-action
Bu on the client side I receive a notification with no deep link. It means that app gets android.intent.action.MAIN as the intent action by tap. Intent's data is null.
I believe I've done everything correctly according: https://docs.amplify.aws/gen1/android/build-a-backend/push-notifications/set-up-push-notifications/ https://docs.amplify.aws/gen1/android/build-a-backend/push-notifications/register-device/ https://docs.amplify.aws/gen1/android/build-a-backend/push-notifications/record-notifications/
What could be the problem?
Reproduction steps (if applicable)
Code Snippet
Log output
amplifyconfiguration.json
GraphQL Schema
Additional information and screenshots
No response