We’re using NotificationCompat.MessagingStyle
for some push-notifications in our Android app. Notifications are recieved via OneSignal SDK, and we implement INotificationServiceExtension
to mutate them, including the aforementioned MessagingStyle
.
When we receive a new message notification, we want to add the new message to an existing notification if it exists, otherwise display a new one.
Currently this requires fetching the old notification by its locusId
, copying its style, canceling it and displaying a new one with the new message added. I am not sure if it’s the correct way. I should also mention that no notification id
s are tracked, they a auto-generated by OneSignal.
Here’s a simplified implementation of INotificationServiceExtension
:
class PushNotificationService : INotificationServiceExtension {
override fun onNotificationReceived(event: INotificationReceivedEvent) {
when (val type = event.notification.additionalData?.getString("type")) {
"new_message" -> {
// Can't be null if type exists
val data: NewMessagePushData = event.notification.additionalData!!.let {
Json.decodeFromString(it.toString())
}
event.applyConversationStyle(data)
}
// ...
}
}
private fun INotificationReceivedEvent.applyConversationStyle(
data: NewMessagePushData
) {
val notificationManager = context.getSystemService(FirebaseMessagingService.NOTIFICATION_SERVICE)
as NotificationManager
val previousNotification = notificationManager
.activeNotifications
.find {
it.notification.locusId?.id == data.chatId.toString()
}
val usersDao = getService(context).usersDao()
notification.setExtender { notification ->
val (user, icon) = runBlocking {
val user = /* Fetch user from local DB*/
val icon = user?.let {/*Fetch user's avatar and process it for display*/}
user to icon
}
if (user == null) return@setExtender notification
val person = /*Build an androidx.core.app.Person from user data*/
val style = previousNotification?.let {
NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(it.notification)
} ?: NotificationCompat.MessagingStyle(
/*Build an androidx.core.app.Person for current user*/
)
// This is questionable!
previousNotification?.id?.let {
OneSignal.Notifications.removeNotification(it)
}
notification
.setContentTitle(user.fullName.asString(context))
.setStyle(
style
.addMessage(
NotificationCompat.MessagingStyle.Message(
data.body,
System.currentTimeMillis(),
person
)
)
)
.addPerson(person)
.setLargeIcon(icon?.toIcon(context))
.setCategory(Notification.CATEGORY_MESSAGE)
.setLocusId(LocusIdCompat(data.chatId.toString()))
.setShortcutInfo(context.createConversationShortcutIfNeeded(
data = data,
user = user,
person = person,
icon = icon
))
}
}
}
What is the correct and standard way of doing what I want? Should I bring my messages DAO into this service to fetch messages? Should I ask the backend team to keep track of notification id
s and send the same ones for any particular conversation so the system auto-mutates them for me? Or should I keep track of those id
s myself?