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

Viewed 1922

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.

2 Answers

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'];
        }

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.

Related