Collapsing FCM Notification? Like a pro!

Chetan Sachdeva
Fueled Engineering
Published in
4 min readNov 6, 2017

After rambling through the web on “How to collapse FCM notifications of similar type”, I couldn’t really find any useful resource. Only thing I knew was that Firebase will send a collapse_key in its RemoteMessage which can be used to identify the notification type. I wanted to achieve something like this:

So, I took down all the requirements on a piece of paper:

  1. A datatype to handle something like one key : multiple values where key would be the collapse_key and values would be the Notification Ids. Possibly a HashMap<String, List<Integer>>.
  2. A mechanism to keep track of the notifications to collapse and save this data in some kind of cache.

I stumbled upon Guava’s Multimap but if I were using it, the implementation would become Multimap specific. So I ended up creating a wrapper class MultiValuedMap<String, Integer> which fulfils my requirement.

Handling Notifications Elegantly 💫

I took inspiration from this very good article by Jovche Mitrejchevski that expounds on how to handle Android Notifications elegantly.

In this article, Jovche uses Dagger and the best practices to achieve the intended. Here’s the flow mentioned:

AppPushNotification

AppPushNotification

AppPushNotification is responsible for resolving PushNotificationItem. It also decides when to show/hide a notification.

The Code

The Methods

  • push() : pushes a notification. Entails all the logic to resolve a PushNotificationItem, create a channel and show/hide the notification.
  • createChannel() : creates a notification channel based on the android_channel_id and returns AppNotificationChannel. To know more about notification channels, see documentation.
  • notify() : notifies the NotificationManager to show a notification.
  • cancel() : cancels a notification from NotificationManger for given id.

The Dependencies

Collapsing Notifications Elegantly 💫

CollapsingNotificationManager is one of the dependencies injected in AppPushNotification which manages collapsing of notifications.

CollapsingNotificationManager

The Algorithm

  1. Notifications will collapse based on collapse_key from RemoteMessage. Ergo, you should be sending a payload with a collapse_key. By default, collapse_key is the app package name registered in Firebase.
  2. When the first notification (of say type_a) is triggered, the usual notification will be shown.
  3. When second notification (of say type_a) is triggered, it is added to the queue and if the size of this list of type_a notification is greater than 1, flag shouldCollapse is set to true.
  4. Hence, the previous notification is cleared and the collapsing text will be shown based on the type. In this case, it will be “You have 2 notifications of Type-A”.
  5. Similar steps will be followed for type_b notifications and so on.
  6. When user taps on or dismisses this notification from Notification Tray, this list of type_a notifications cleared. MainActivity handles the tap whereas NotificationDismissTracker takes care of dismissal.

The Code

Writing functions was never this “fun”. Thanks to Kotlin :)

The Methods

  • getNotificationsToCollapse() : returns the NOTIFICATION_IDS to collapse so that the previous notification can be cleared if required.
  • clearNotificationsToCollapse() : clears the NOTIFICATION_IDS to collapse of a particular type or NOTIFICATION_KEY when :

a. The user taps on a particular notification (see MainActivity).

b. The user dismisses a notification (see NotificationDismissTracker) from the Notification Tray.

The Dependencies

  • CollapsingNotificationStore : persists all the NOTIFICATION_IDS pertaining to a particular type or NOTIFICATION_KEY, in this case collapse_key. It makes use of the PreferenceManager to get and put the COLLAPSING_NOTIFICATIONS ie. a MultiValuedMap<String, String>.

Github Sample

There! We collapsed our notifications based on type. If this post made you happy, you can sing the Pharrell Williams song and clap along 👏🏻😊

Here is a blog to help you test notifications easily.

Special thanks to Jovche Mitrejchevski for the wonderful post, my friends and colleagues Arun Sasidharan for helping me create the flowcharts and Garima Jain for her valuable feedback 🙏🏻

--

--