flutter_local_notifications icon indicating copy to clipboard operation
flutter_local_notifications copied to clipboard

[flutter_local_notifications] Allow notification actions on ios to work with remote (non-local) notifications

Open Jonny1987 opened this issue 3 months ago • 2 comments

Changes

  • Allow didReceiveNotificationResponse to continue even if isAFlutterLocalNotification is false
  • When isAFlutterLocalNotification is false, the notification's payload is the whole of response.notification.request.content.userInfo rather than just the PAYLOAD key, since it doesn't exist for non-local notifications

Why

Currently, to show notifications you need to send a data only message so that flutter_local_notifications can show the message, which will allow the action button to work correctly. (including a notification in the notification message when sending, as well as a category, will cause flutter_firebase_messaging to show it automatically but actions don't work). However, data only messages on iOS are not completely reliable and are sometimes delayed or never get received.

So it makes sense to allow actions to function correctly when a notification message that contains a notification and a category is received and automatically shown by flutter_firebase_messaging.

Notes

Since the payload is set to response.notification.request.content.userInfo rather than response.notification.request.content.userInfo['PAYLOAD'] (since the PAYLOAD key won't exist if it's not a local notification), this will include other keys which weren't sent in notification.data like the aps block, and other keys such as gcm.message_id,google.c.a.e, google.c.fid, google.c.sender.id etc.

In order for these to not appear in the payload of the response object (NotificationResponse) returned by the method getNotificationAppLaunchDetails and used in the functions given for onDidReceiveNotificationResponse and onDidReceiveBackgroundNotificationResponse they have been filtered out by looking at what the firebase messaging filters out in it's method remoteMessageUserInfoToDict method.

Another thing is that FirebaseMessaging.onMessageOpenedApp.listen can't be used on iOS (but should still be used for android) because it's effectively replaced by onDidReceiveNotificationResponse in flutterLocalNotificationsPlugin.initialize().

Jonny1987 avatar Sep 05 '25 13:09 Jonny1987

I've now used method swizzling to block the onMessageOpenedApp channel message of firebase messaging so that the FirebaseMessaging.onMessageOpenedApp.listen will not get used for iOS since flutter_local_notification's onDidReceiveNotificationResponse is used for all notificaitons (local and non-local)

Jonny1987 avatar Sep 07 '25 01:09 Jonny1987

After looking at what you've mentioned, this is what I've come to understand

  • You noticed there are issues with data only messages sent via push notifications so looked for a more reliable solution that requires use of notification messages
  • Your changes now impact how the FCM plugin itself behaves

Can you please confirm if the following is correct? If so, then this is a specific to your case. There may be others that could be benefit from it but is a scenario where forks or a custom implementation are more appropriate. Merging this will affect the FCM plugin's behavior specific to your case but will affect the rest of the community. It also creates an inconsistent mental model as this plugin, which is for local notifications, is now handling push/remote notifications. Additionally, there is inconsistent behaviour that you mentioned between Android and iOS

MaikuB avatar Nov 15 '25 03:11 MaikuB