question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[messaging] Ability to change the notification before it's sent to the system tray

See original GitHub issue

What feature would you like to see?

Hi, is there anything on the roadmap to provide the ability to customise the notification before it’s sent to the system tray. I’m a maintainer of notifee, and we recently added support to do this with iOS, we’d love to be able to do it with Android too.

Currently, the only option there seems to be is to send data messages. A couple of issues with this method are that you need to send two different types of messages based on whether the device is android or iOS, and having to keep track of which platform the token is registered with.

In addition to platform-dependent code, there’s also different background restrictions for data-only vs notification messages (ref here).

On iOS, you can alter the notification using a Notification Service Extension where you have a brief amount of time to modify the notification before it’s displayed to the user. in addition to the flexibility that message.apns.aps object offers where you can add a categoryId, sound, threadId e.t.c.

One possible solution could be to allow FirebaseMessagingService.onMessageReceived to be called for all app states, maybe a check somehow to see if the app does supports this, if not, default to handling with FCM? If this was possible, the one issue I do see with this, is that it could clash with other libraries like FlutterFire and react-native-firebase as you can only have one FirebaseMessagingService per app.

Another solution, which I think seems way easier and less intrusive is to have a separate service, like how iOS works, to alter the notification and nothing else.

I can see how this could be a big f/r, and maybe there’s reasons that it’s not been done?

The other possible solution is to expand the predefined set of user-visible keys for message.android, to include group and other NotificationCompat properties where possible.

To summarise, the two pain points I think there is at the moment with Android is:

  • the options allowed via message.android is limited.
  • no ability to intercept the notification before it’s shown when the app is in background

How would you use it?

Tell us how you’d use this feature in your app.

This feature would allow users of this library to send notification messages and customise the notification before it’s finally sent to the system tray.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:20
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
sfuquacommented, Feb 23, 2022

The comparison to the iOS Notification Service Extension is a good one - I think Apple has a fairly elegant solution here in allowing an app to effectively “tamper” with a notification payload before it’s handled by the system. I’d love to do exactly the same thing in Android Firebase land - mutate the RemoteMessage before the SDK handles it.

I have legacy services that are sending a notification payload with my FCM messages. It’s not impossible to change these to data only, but it’s costly, as it’s a breaking change for existing clients and requires me to spend some political capital on getting the services updated and redeployed with new payload versions - and I have to repeat that per notification type, because nearly all of them are impacted. Allowing a client to intercept the payload and remove the “notification” blob before the SDK handles it would be a godsend.

Some extensible method on FirebaseMessagingService, like overrideMessageProperties(RemoteMessage), that an app can implement would do just the trick.

edit: It looks like this is something that could be handled fairly trivially with just changes to the existing Java code in FirebaseMessagingService.dispatchMessage, specifically before the current isNotification check that then routes the message to a DisplayNotification. We’d just need a protected function that allows inspecting the Intent and then opting out of automatic notification behavior.

I can’t find docs describing the current SDK behavior for isNotification, where it’s looking for “gcm.n.e” in the payload via https://github.com/firebase/firebase-android-sdk/blob/b2aed41639c6a9590fa4d31098805763ceb6eb9f/firebase-messaging/src/main/java/com/google/firebase/messaging/Constants.java#L155

I have to assume this is based on historical GCM behavior and how the Google services format the notification before it hits the Firebase SDK client code, so it’s not as trivial as letting an app receive a RemoteMessage and then tamper with it.

Is there a design reason not to allow an app to opt-out of this behavior? I’m open to potentially creating a PR if we can reach consensus on the approach?

1reaction
sfuquacommented, Sep 30, 2022

For anyone following this issue - since the Firebase team is not showing any interest in my PR to tweak the API for this scenario, my app team has been working around this problem with a custom FirebaseMessagingService that overrides handleIntent to intercept specific notification Intents before they’re sent to Firebase SDK and automatically displayed, and instead displaying them ourselves.

This seems to work just fine despite being an undocumented workaround. I have not received any reports of it causing problems despite being live for a few months.

The approach is based on how the SDK’s service works under the covers and is something like:

// this is inside a custom FirebaseMessagingService which we've hooked up in our AndroidManifest

// 1. excessively document for your team with links to GitHub issues, PRs, StackOverflow, etc
// 2. emphasize that this is a hack which risks breaking in future Firebase SDK updates :(
// 3. dream of an officially supported API for this scenario
@Override
public void handleIntent(Intent intent) {
  Bundle extras = intent.getExtras();
  
  // try/catch around this to be defensive; default to super.handleIntent
  RemoteMessage message = new RemoteMessage(extras);
  
  RemoteMessage.Notification notificationData = message.getNotification();
  // short-circuit if this is not a display notification
  if (notificationData == null) { super.handleIntent(intent); return; }
  
  // 1. filter on the notification however you want using the data payload, clickAction, etc
  // 2. manually display notifications that match your filter, and then return
  // 3. fall-through to this for everything else...
  super.handleIntent(intent);
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Notifications and the Notification Area - Win32 apps
The notification area is a portion of the taskbar that provides a temporary source for notifications and status.
Read more >
System Tray Icons (Context Menus and Notifications) - YouTube
Learn how to implement a system tray icon (NotifyIcon) in a WPF application. A system tray icon allows a WPF application to be...
Read more >
Customize Taskbar, Notification Area and Action Center in ...
To configure the notification area, you can either right-click on the taskbar, choose Properties, and click on the Customize button next to ...
Read more >
Notifications Overview | Android Developers
A notification is a message that Android displays outside your app's UI to provide the user with reminders, communication from other people, or...
Read more >
Farewell to the notification area - Canonical
Together, these elements were controlled by a program called systray.exe . But at some point, Microsoft decided to make this mechanism generic, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found