eliysha
eliysha

Reputation: 75

Flutter Firebase messaging : open a new screen on background notification received

The background handler is called, everything works fine but I don't know how to get a BuildContext instance for navigating to a new screen. I have this handler


Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    var notificationData = message.data;
    var view = notificationData['view'];

    if(view == 'MessagesScreen') {
        Map<String, dynamic> videoData = json.decode(
            notificationData['video_data']);
        VideoItem videoItem = VideoItem.fromJson(videoData);

       Navigator.pushNamed(context, '/playerScreen', arguments:{videoItem});
    } else {
        view = '/$view';
        Navigator.pushNamed(context, view);
    }

    return Future<void>.value();
}

It's called like this

await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);

I'm using Firebase messaging : 9.1.2

Any idea how to achieve this ?

Thx

Upvotes: 3

Views: 2957

Answers (2)

krishnakumarcn
krishnakumarcn

Reputation: 4179

This behavior is not possible directly. The backgrounder handler is spawned as a new isolate where you cant do any UI-related operations.

You can perform isolate communication using listening to a port from the UI thread and sending your data to this port from the background isolate

Listen on UI thread:

  ReceivePort _port = ReceivePort();
  IsolateNameServer.registerPortWithName(_port.sendPort,'port_name');
  _port.listen((dynamic data) {
       /// navigate here
     });

Send message, inside backgroundHandler:

final SendPort send = IsolateNameServer.lookupPortByName('port_name');
send.send(true);

Upvotes: 6

Luis A. Chaglla
Luis A. Chaglla

Reputation: 600

If you want to navigate when a user taps on the notification whilst the app is terminated try this:

FirebaseMessaging.instance
    .getInitialMessage()
    .then((RemoteMessage? message) {
  if (message == null) return;

  var notificationData = message.data;
  var view = notificationData['view'];

  if(view == 'MessagesScreen') {
      Map<String, dynamic> videoData = json.decode(
          notificationData['video_data']);
      VideoItem videoItem = VideoItem.fromJson(videoData);

    Navigator.pushNamed(context, '/playerScreen', arguments:{videoItem});
  } else {
      view = '/$view';
      Navigator.pushNamed(context, view);
  }
  
});

Check this example: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/firebase_messaging/example/lib/main.dart#L116

Upvotes: 4

Related Questions