Butch
Butch

Reputation: 25

Flutter Firebase Messaging trigger onLaunch

So I have a question, because I am not fully understand something. So I wrote a simple app, to try something, so I send a message from Firebase via Firebase Cloud Messaging. I use the firebase_messaging flutter plugin (7.0.3 version). It just does a simple thing to get the message and navigate to another page. My problem is the following one, the onMessage and the onResume function works perfectly, but when the app is terminated and I click on the notification the app opens but nothing happens. So I read the documentation and I found this picture The third row says, that the data is lost... Does this mean that I lost every data in the payload? My code is here if it helps

 static final NavigationService _navigationService =
      loc.Locator.locator<NavigationService>();
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

  Future<void> reqPermission() async {
    bool permission = true;
    if (Platform.isIOS) {
      permission = await _firebaseMessaging.requestNotificationPermissions();
    }
    if (permission) {
      _firebaseMessaging.configure(
        onMessage: (Map<String, dynamic> message) async {
          print(message);
          await _navigationService.navigateTo(NewPage.routeName);
        },
        onLaunch: (Map<String, dynamic> message) async {
          print('onLaunch $message');
          await _navigationService.navigateTo(NewPage.routeName);
        },
        onResume: (Map<String, dynamic> message) async {
          print('onResume $message');
          await _navigationService.navigateTo(NewPage.routeName);
        },
        onBackgroundMessage: _myBackgroundHandler,
      );
    }
  }

Upvotes: 1

Views: 996

Answers (2)

markbeij
markbeij

Reputation: 141

I recently asked this question on GitHub, see: https://github.com/FirebaseExtended/flutterfire/issues/5098#issuecomment-783444919

That was true for the old version and it required a native workaround. The latest non-nullsafety version firebase_messaging: ^8.0.0-dev.14 will work from a terminated state (unless you force-quit the app on android). The updated documentation is at https://firebase.flutter.dev/docs/messaging/usage#receiving-messages

Upvotes: 1

Hakkı Akut
Hakkı Akut

Reputation: 631

you can send notifiction and data with fcm it supports notifiction on terminated but not data. You can able send body and title in notification so if you want to need basic notification (which only has title and body). You can send it with using notification. If you need more than that, you can use it with flutter_local_notifications package in onLaunch. https://pub.dev/packages/flutter_local_notifications

This is how to use tokens

_firebaseMessaging.onTokenRefresh.listen((newToken) {
      User _currentUser = FirebaseAuth.instance.currentUser;
      FirebaseFirestore.instance
          .doc("tokens/" + _currentUser.uid)
          .set({"token": newToken});
    });

and you can push it like that.

  Future<bool> sendNotification(
      {@required Map<String, dynamic> messageMap,
      @required AppUser appUser,
      @required String token}) async {
    String url = "https://fcm.googleapis.com/fcm/send";
    String _firebaseKey ="<your key>"

    Map<String, String> headers = {
      "Content-type": "application/json",
      "Authorization": "key=$_firebaseKey"
    };
    String json =
        '{ "to" : "$token", "data" : { "message" : "${messageMap["message"]}", "sendBy": "${appUser.name}", "messageType": "${messageMap["messageType"]}", "sendById" : "${appUser.userId}" } }';
    http.post(url, headers: headers, body: json);
    return true;
  }

FCM configurtion

_firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        //getNotificationMessage(message["data"]["message"]);
        if(message["data"]["messageType"]=="text"){
          NotificationHandler.showNotification(message); // Flutter Local Notification method
        } else{
          NotificationHandler.showBigPictureNotification(message);// Flutter Local Notification method
        }
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        if(message["data"]["messageType"]=="text"){
          NotificationHandler.showNotification(message);// Flutter Local Notification method
        } else{
          NotificationHandler.showBigPictureNotification(message);// Flutter Local Notification method
        }
      },
      onResume: (Map<String, dynamic> message) async {
        if(message["data"]["messageType"]=="text"){
          NotificationHandler.showNotification(message);// Flutter Local Notification method
        } else{
          NotificationHandler.showBigPictureNotification(message);// Flutter Local Notification method
        }
      },
      onBackgroundMessage: myBackgroundMessageHandler,
    );
  }

This is background message handler

Future<void> myBackgroundMessageHandler(Map<String, dynamic> message) async {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
    if(message["data"]["messageType"]=="text"){
      NotificationHandler.showNotification(message);// Flutter Local Notification method
    } else{
      NotificationHandler.showBigPictureNotification(message);// Flutter Local Notification method
    }

  }

  return Future.value();
}

This is how i did it in my project

Upvotes: 2

Related Questions