[flutter_local_notifications] Allow notification actions on ios to work with remote (non-local) notifications
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().
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)
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