tanweer anwar
tanweer anwar

Reputation: 127

Firebase messaging onResume, onLaunch or onBackgroundMessage are never called

I am using Firebase Cloud Messaging package for flutter. I want that whenever a user taps on the received notification, the flutter app opens and navigate to a particular screen depending on the data sent by fcm.

But I am not able to achieve desired behaviour when either app is in the background or app is closed since onResume and onLaunch handler are never called. I have tried a number of solution like creating notification channel , using package like flutter_local_notifications etc. But nothing worked for me.

Here is my FirebaseMessagingService class to handle fcm related tasks

class FirebaseMessagingService {
  final FirebaseMessaging _fcm = FirebaseMessaging();
  final RouterService _routerService = locator<RouterService>();
  final LocalStorageService _localStorage = locator<LocalStorageService>();
  Future initialise() async {
    if (Platform.isIOS) {
      _fcm.requestNotificationPermissions(IosNotificationSettings());
    }
    _fcm.configure(
        onMessage: (Map<String, dynamic> message) async {
          Map<String, dynamic> arguments = {};

          Map<String, dynamic> data = message['data'];
          if (data.containsKey('argument')) {
            if (data.containsKey('value')) {
              arguments[data['argument']] = data['value'];
            }
          }
          _routerService.navigationKey.currentState
              .pushReplacementNamed('${data['route']}', arguments: arguments);
        },
        onLaunch: (Map<String, dynamic> message) async {
          Map<String, dynamic> arguments = {};
          Map<String, dynamic> data = message['data'];
          if (data.containsKey('argument')) {
            if (data.containsKey('value')) {
              arguments[data['argument']] = data['value'];
            }
          }
          _routerService.navigationKey.currentState
              .pushReplacementNamed('${data['route']}', arguments: arguments);
        },
        onResume: (Map<String, dynamic> message) async {
          Map<String, dynamic> arguments = {};

          Map<String, dynamic> data = message['data'];
          if (data.containsKey('argument')) {
            if (data.containsKey('value')) {
              arguments[data['argument']] = data['value'];
            }
          }
          _routerService.navigationKey.currentState
              .pushReplacementNamed('${data['route']}', arguments: arguments);
        },
        onBackgroundMessage: _myBackgroundMessageHandler);
  }

  static Future<dynamic> _myBackgroundMessageHandler(
      Map<String, dynamic> message) async {
    final RouterService _routerService = locator<RouterService>();
    if (message.containsKey('data')) {
      // Handle data message
      Map<String, dynamic> arguments = {};
      Map<String, dynamic> data = message['data'];
      if (data.containsKey('argument')) {
        if (data.containsKey('value')) {
          arguments[data['argument']] = data['value'];
        }
      }
      _routerService.navigationKey.currentState
          .pushReplacementNamed('${data['route']}', arguments: arguments);
    }

    if (message.containsKey('notification')) {
      // Handle notification message
      final dynamic notification = message['notification'];
    }
  }
}

Can anyone help me out with the issue??

Upvotes: 0

Views: 674

Answers (1)

I found a solution for that. Firstly you have to add this code into your manifest:

<intent-filter>
    <action android:name="FLUTTER_NOTIFICATION_CLICK"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

When you have done that, you have to pass your firebase cloud messaging:

click_action => FLUTTER_NOTIFICATION_CLICK

Then you can also pass as data for example route => detailScreen.

When you mave done that, you can call firebase messaging functions like onResume or OnLaunch, by checking that rout you passed in the FCM.

When you check the route you can navigate any screen with this function:

//PRIVATE METHOD TO HANDLE NAVIGATION TO SPECIFIC PAGE
void _navigateToSignalsPage(Map<String, dynamic> message) {
  final MessageBean item = _itemForMessage(message);
  // Clear away dialogs
  //  Navigator.popUntil(context, (Route<dynamic> route) => route is PageRoute);
  if (!item.route.isCurrent) {
    print('heey girl ${item.route}');
    Navigator.push(
        context, MaterialPageRoute(builder: (context) => HomePage(selectedPage: 0,)));
  }
}

Upvotes: 1

Related Questions