Flutter - Firebase Cloud Messaging, Data Message is not received on iOS

1,543

Solution 1

IOS messages come with a different structure, you don't need 'data' for IOS an example could be

     if(Platform.isAndroid){
          roomId = message['data']['chatRoomId'];
          senderId = message['data']['senderId'];
        }else if(Platform.isIOS){//without data
          roomId = message['chatRoomId'];
          senderId = message['senderId'];
        }

Solution 2

On iOS, the data is directly appended to the message and the additional data-field is omitted. To receive the data on both platforms, your myBackgroundMessageHandler() function should look like this:

Future<void> myBackgroundMessageHandler(Map<dynamic, dynamic> message) async {
    var data = message['data'] ?? message;
    print(data);
    String expectedAttribute = data['expectedAttribute'];
  }

You can learn more about this on the Firebase Messaging Flutter documentation, under the "Notification messages with additional data" section.

Share:
1,543
Admin
Author by

Admin

Updated on December 22, 2022

Comments

  • Admin
    Admin over 1 year

    Notification handler

    void firebaseCloudMessagingListeners() {
        _firebaseMessaging.configure(
          onMessage: (Map<String, dynamic> message) async {
            print('onMessage ==> $message');
            messageHandler(message);
          },
          onResume: (Map<String, dynamic> message) async {
            print('onResume ==> $message');
            messageHandler(message);
          },
          onLaunch: (Map<String, dynamic> message) async {
            print('onLaunch ==> $message');
            messageHandler(message);
          },
          onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
        );
      }
    
      static Future<dynamic> myBackgroundMessageHandler(
          Map<String, dynamic> message) {
        print('onBackgroundMessage ==> $message');
        if (message.containsKey('data')) {
          final dynamic data = message['data'];
          print('$data');
        }
    
        if (message.containsKey('notification')) {
          final dynamic notification = message['notification'];
          print('$notification');
        }
    
        return null;
      }
    

    POST https://fcm.googleapis.com/fcm/send

    {
       "to": "myFCMToken",
       "priority": "high",
       "data": {
          "click_action": "FLUTTER_NOTIFICATION_CLICK",
          "data_title": "data_title",
          "data_body": "data_body"
       },
       "notification": {
          "title": "Good Night",
          "body": "Wish you have a nice dream..",
          "sound": "default"
       }
    }
    

    When I sent notification with payload above, notification is delivered to the system tray and when I tapped it, i had these three with following cases:

    1. App is in Background (closed/terminated), the "data" is presented and onLaunch method is called.
    2. App is in Background (minimized), the "data" is missing, onResume method is not called.
    3. App is in Foreground, the "data" is missing, onMessage method is not called.

    The question is, how to receive or handle that "data" with notification is also delivered to system tray? Any help would be appreciated.