4

I want to switch to a screen when an FCM background message receives. But for this context is required which I definitely don't have inside FirebaseBackgroundMessageHandler so after searching on the internet and I found that I can get the current context from the NavigatorKey so I created this global variable:

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

and this on my material app:

runApp(GetMaterialApp(
    navigatorKey: navigatorKey,
    home: const MyHomePage(),));

Now, whenever I receive a background message I try to switch to the desired screen but I always get the null context so couldn't Push. Navigating through GetX also throws an error. What am I missing? Please help!!!!

Firebase background handler:

Future<dynamic> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  if(message.data['test'] == '123'){
    Navigator.of(navigatorKey.currentContext!).push(MaterialPageRoute(builder: (context) =>const Wallet()));
  }
}
Siddharth Mehra
  • 1,691
  • 1
  • 9
  • 32

1 Answers1

3

According to the documentation of Firebase background messages:

Since the handler runs in its own isolate outside your applications context, it is not possible to update application state or execute any UI impacting logic. You can however perform logic such as HTTP requests, IO operations (updating local storage), communicate with other plugins etc.

So if your application is in the background, you can't initiate the navigation the way you would like. If you present the user with a notification, the user can decide to click it, and then you can use FirebaseMessaging.onMessageOpenedApp. In this handler you will be able to handle navigation.

Peter Koltai
  • 8,296
  • 2
  • 10
  • 20
  • Thanks but my `FirebaseMessaging.onMessageOpenedApp` never invokes. This is my code: `FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { print(message.toString()); Get.to(()=> const Wallet()); });` I dont know what I am doing wrong. – Siddharth Mehra Jan 11 '22 at 08:50
  • 1
    So your notifications are displayed when the app is in the background, the user clicks on it, and `onMessageOpenedApp` does not execute? – Peter Koltai Jan 11 '22 at 09:11
  • My bad, it does execute if I send I visible notification but will it also execute when I show notification using [this](https://pub.dev/packages/flutter_local_notifications) package? – Siddharth Mehra Jan 11 '22 at 10:11
  • 1
    There is an `initialize` method of `FlutterLocalNotificationsPlugin`, which you have to call when setting up, and with this method you can setup an `onSelectNotification` function, and that will be executed when user clicks on a notification displayed using this package. – Peter Koltai Jan 11 '22 at 11:27
  • How does this work in case of packages like callkeep? Where the app is terminated and the the callkeep package shows the native calling screen. The listeners are placed in the `firebaseMessagingBackgroundHandler` and as said above, the use of `navigation.currentContext` failes because it is in the other isolate. What can be done on tap of the Accept button? – thewebjackal Jul 12 '23 at 11:26