Android badge counts
When the smart badge count (Send background notifications for unread count changes) feature is enabled, Atomic sends a background push notification whenever a change to a customer's card feed causes their unread count to change. This includes a card being published, snoozed, dismissed, or viewed on another device.
On iOS, badge count updates are handled automatically by the system. On Android, it is the responsibility of the host app to take the unread count from the notification payload and use it to inform the user. This page describes a pattern for doing that.
Before enabling this setting in production, thoroughly test it in a non-production environment, including on older versions of your app that are already in the wild. This setting causes background FCM notifications to be sent with empty titles and content. If your app is configured to display these as local notifications, users may see empty notifications pop up.
Enable the setting in the workbench
Enable Send background notifications for unread count changes under Configuration > Notifications > Notification Badge Settings. See Enable notification badge settings for details.
Badge counts on Android
On modern Android launchers, the badge count shown on the app's home screen icon is inherited from the active notifications present in the notification drawer. As notifications are added and dismissed, the launcher updates the badge accordingly. When the last notification is dismissed, the badge disappears.
In the past, a library (ShortcutBadger) was used to set badge counts directly, but it is now deprecated and only supports very old launchers.
Because the badge count cannot be set directly through an API, we need a different pattern to reflect the unread count: a local notification.
Showing an unread count
You can show the unread count with a local "You have X unread messages" notification. The count updates automatically as cards are published or viewed on other devices, even while the app is in the background. When there are no unread cards, the notification is cancelled automatically and the badge disappears.
The code
The examples below assume you already have push notifications set up in your app, and only cover the changes needed for the badge count. The text, icon, and tap behaviour should be customised to suit your app.
Add a notification channel for these messages
It is best practice to use a separate notification channel for these messages. They are generally of lower importance than other push notifications, and a user may want to disable them while still receiving other push notifications.
Create the channel in the onCreate method of your application:
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Unread Messages"
val descriptionText = "Notifications for new unread messages"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(UNREAD_MESSAGES_CHANNEL_ID, name, importance).apply {
description = descriptionText
}
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
Read the unread count in onMessageReceived
In the onMessageReceived function of your FirebaseMessagingService, inspect the push notification to retrieve the unread count. Then either post an updated unread messages notification, or cancel it:
val notificationCount = remoteMessage.data["notification_count"]?.toIntOrNull() ?: 0
if (notificationCount >= 1) {
sendUnreadMessageNotification(notificationCount)
} else {
cancelUnreadMessageNotification()
}
Send the unread messages notification
This is example code for the unread messages notification. You will need to customise the text and icon, and you may want to set it up to take the user to a specific place in your app, depending on how your app's navigation is structured:
private fun sendUnreadMessageNotification(unreadCount: Int) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notificationId = UNREAD_MESSAGES_NOTIFICATION_ID // A unique ID for this notification, used to cancel it when the unread count is 0
// You may want to make this notification open the screen containing your Atomic stream container
val notificationBuilder = NotificationCompat.Builder(this, UNREAD_MESSAGES_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("YourApp")
.setContentText("You have $unreadCount unread messages") // This copy can be anything; including the number is optional
.setNumber(unreadCount) // This sets the badge count for supported launchers
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
notificationManager.notify(notificationId, notificationBuilder.build())
}
Cancel the unread messages notification
To cancel the notification, use the same ID that was used to send it:
private fun cancelUnreadMessageNotification() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notificationId = UNREAD_MESSAGES_NOTIFICATION_ID // The same ID used to show the notification
notificationManager.cancel(notificationId)
}
Testing
This feature relies on several services interacting (Atomic, Firebase, your app's code, and the Android system), so it is important to thoroughly test different scenarios:
- If you use cards with push notifications enabled, or intend to in the future, verify that this functionality works alongside the unread count notifications.
- Android versions and devices from different vendors can behave differently, so test across a range of devices and OS versions.