无法使用 FCM onBackgroundMessage 导航到特定屏幕

时间:2021-06-19 07:35:49

标签: flutter firebase-cloud-messaging

当我的应用程序被终止时收到通知时,我想在点击通知时导航到我选择的特定屏幕。我已经添加了导航代码,但应用程序没有导航到该屏幕。相反,该应用会打开并导航到第一个屏幕。

这是我的代码:

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    RemoteNotification notification = message.notification;
   flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                channel.description,
                icon: '@drawable/splash',
                playSound: true
              ),
            ));

            // This does not seem to work as I am not directed to OrdersScreen 
            navigatorKey.currentState
                      .push(MaterialPageRoute(builder: (_) => OrdersScreen()));
}


void initState(){ 
    super.initState();
    var initializationSettingsAndroid  = AndroidInitializationSettings('@drawable/splash');
    var initializationSettings = InitializationSettings(android:initializationSettingsAndroid);
    flutterLocalNotificationsPlugin.initialize(initializationSettings);
     FirebaseMessaging.instance
        .getInitialMessage()
        .then((RemoteMessage message) {
      if (message != null) {
          navigatorKey.currentState
                       .push(MaterialPageRoute(builder: (_) => OrdersScreen()));
      }
    });

}

2 个答案:

答案 0 :(得分:0)

对我来说,我正在使用很棒的通知来做到这一点。这是在主屏幕内完成的。 我不知道这是否是最好的方法,但它非常适合我。 您还可以使用 receivedNotification.buttonKeyPressed 区分通知内的按钮(如果有)。

如果用户没有按下按钮(或者没有按钮),那么没有按钮按键按下,我在我的代码中处理了这个。

很棒的通知链接:https://pub.dev/packages/awesome_notifications

////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////// HOME SCREEN   //////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    try {
      AwesomeNotifications().actionStream.listen((receivedNotification) {
        // print(receivedNotification.toString());
        // print(receivedNotification.buttonKeyPressed.toString());
        print("I am listning");
        //////////////     REPLY  button
        if (receivedNotification.buttonKeyPressed == "REPLY") {
          Navigator.of(context).pushNamed(
            ReplayInterface.routeName,
          );
        }
        /////////////////  REJECT  button
        else if (receivedNotification.buttonKeyPressed == "REJECT") {
          getReject();
          Navigator.of(context).pushNamed(RegectInterface.routeName);
        }
        /////////////////  BODY Notification
        else if (receivedNotification.buttonKeyPressed != "REJECT" &&
            receivedNotification.buttonKeyPressed != "REPLY") {
          print(receivedNotification.buttonKeyPressed);
          Navigator.of(context).pushNamed(Counter.routName);
        }
        /////////////////  NOT NOTIFICATION
        else {
          return;
        }
      });
    } catch (e) {
      print("e is $e");
      Navigator.of(context).pushReplacementNamed("/");
    }
    super.initState();
  }

`

答案 1 :(得分:0)

如果您使用的是 firebase_messaging 版本 10.0.0 或更高版本,以下代码应该可以工作。 您应该在第一个屏幕中调用 handlePushNotification() 函数。 要保存最后一个前景屏幕路径,您可以使用 shared_preferences 或其他解决方案。

这是您的问题的一个非常基本的示例。

void handlePushNotification() {
    //FOREGROUND MESSAGES
    FirebaseMessaging.onMessage.listen((message) {
      _showSnackBar(message: message);
    });
    //BACKGROUND MESSAGES - ONRESUME
    FirebaseMessaging.onMessageOpenedApp.listen((message) {
     //Detect your current screen if you wish when "onResume" called.
     if( currentScreenPath == 'FirstScreen' ){            
        _navigateSpecificScreen();
     } else {
        debugPrint('Specific screen is already foreground!');
        _showSnackBar(message: message);
     }        
    });
    //BACKGROUND MESSAGES - ONLAUNCH
    if (_firebaseMessaging != null) {
      _firebaseMessaging!.getInitialMessage().then((message) {
        if (null != message) {
          _navigateSpecificScreen();
        }
      });
    }
  }

如果您唯一的问题是在您的应用终止并重新启动时导航到特定屏幕,您可以忽略以下内容。

如果您的应用程序更广泛,您应该更喜欢从一个类中控制所有导航。

也许您可以在 onGenerateRoute 中使用 MaterialApp 属性。 这是一个例子:how to use onGenerateRoute

您可以创建一个函数来跟踪 RouteGenerator 类中哪个屏幕是前景。 您还需要处理 Navigation.of(context).pop()

当 onResume 调用时屏幕已经处于前台时,您不想再次导航它。