How to navigate to desired screen when FCM Background Message received?

152

Similar to the answer that Peter Koltai gave, your background handler is isolated from your application's context and so it's not possible to route to screens (which require a context) directly from your handler.

One possible solution is to implement an Android service using native code that communicates with Flutter via a MethodChannel and on the event that a call is accepted, you can navigate screens.

Share:
152
Siddharth Mehra
Author by

Siddharth Mehra

I know nothing but want to know everything!!!

Updated on December 30, 2022

Comments

  • Siddharth Mehra
    Siddharth Mehra over 1 year

    I am having a hard time navigating to a screen when a background FCM message receives. Currently, I am sending an FCM message with some data and when it gets received by a device then it calls this package that shows a calling notification, and when the user clicks on accept call option then I want to open my app and navigate to the desired screen. I use GetX for navigation and when I try to go to another screen it gives this exception: enter image description here

    I have tried almost everything to work this out but I am still unable to solve this problem.

    my FirebaseMessaging.onBackgroundMessage Background handler which receives the notification also listens to user feedback on whether the call is accepted or rejected:

    Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    
    
      var incoming = <String, dynamic>{
        'id': message.data['callerID'],
        'nameCaller': message.data['callerName'],
        'appName': 'Callkit',
        'avatar': message.data['callerImage'],
        'handle': '',
        'type': 0,
        'duration': 30000,
        'extra': <String, dynamic>{'userId': '1a2b3c4d'},
        'headers': <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
        'android': <String, dynamic>{
          'isCustomNotification': true,
          'isShowLogo': false,
          'ringtonePath': 'ringtone_default',
          'backgroundColor': '#0955fa',
          //'backgroundUrl': 'https://i.pravatar.cc/500',
          'actionColor': '#4CAF50'
        }};
      await FlutterCallkitIncoming.showCallkitIncoming(incoming);
    
    
      try {
        FlutterCallkitIncoming.onEvent.listen((event) {
          switch (event!.name) {
            case CallEvent.ACTION_CALL_INCOMING:
              print('INCOMING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
              break;
            case CallEvent.ACTION_CALL_START:
            // TODO: started an outgoing call
            // TODO: show screen calling in Flutter
              break;
            case CallEvent.ACTION_CALL_ACCEPT:
              print('accepted');
              Get.offAll(()=> Incoming(
                  userName: null,
                  userImage: null,
                  userID: null,
                  userUsername: null));
              break;
            case CallEvent.ACTION_CALL_DECLINE:
              print('rejected');
              break;
            case CallEvent.ACTION_CALL_ENDED:
            // TODO: ended an incoming/outgoing call
              break;
            case CallEvent.ACTION_CALL_TIMEOUT:
            // TODO: missed an incoming call
              break;
            case CallEvent.ACTION_CALL_CALLBACK:
            // TODO: only Android - click action `Call back` from missed call notification
              break;
            case CallEvent.ACTION_CALL_TOGGLE_HOLD:
            // TODO: only iOS
              break;
            case CallEvent.ACTION_CALL_TOGGLE_MUTE:
            // TODO: only iOS
              break;
            case CallEvent.ACTION_CALL_TOGGLE_DMTF:
            // TODO: only iOS
              break;
            case CallEvent.ACTION_CALL_TOGGLE_GROUP:
            // TODO: only iOS
              break;
            case CallEvent.ACTION_CALL_TOGGLE_AUDIO_SESSION:
            // TODO: only iOS
              break;
          }
          print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        });
      } on Exception {}
    
    }
    
  • Siddharth Mehra
    Siddharth Mehra over 2 years
    Please spare some time and read the whole question before answering. I have clearly mentioned that I am using GetX to Navigate. Also shared the error I receive when trying to Push to another screen. Furthermore, you can clearly see that I am using this Get.to(()=>AnotherPage()) exact syntax for Pushing to another screen. GetX just won't push without context and I am unable to get context. Tried using navigator key but it just wont help :(
  • easyscript
    easyscript almost 2 years
    Is there any sample code on how to implement screen navigation using native code via MethodChannel? am having this same challenge, in my native code I received notification data but navigating to specific screen is a problem.