Flutter 在颤振中从FCM回调导航到特定屏幕

Flutter 在颤振中从FCM回调导航到特定屏幕,flutter,flutter-dependencies,flutter-web,Flutter,Flutter Dependencies,Flutter Web,下面是我的推送通知管理器。我想在收到通知时导航到特定的屏幕(当应用程序同时处于后台和前台时)。请让我知道我做错了什么 提前谢谢 class PushNotificationsManager { PushNotificationsManager._(); factory PushNotificationsManager() => _instance; static final PushNotificationsManager _instance = PushNotificationsMana

下面是我的推送通知管理器。我想在收到通知时导航到特定的屏幕(当应用程序同时处于后台和前台时)。请让我知道我做错了什么

提前谢谢

class PushNotificationsManager {
PushNotificationsManager._();
factory PushNotificationsManager() => _instance;
static final PushNotificationsManager _instance =
PushNotificationsManager._();

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
bool _initialized = false;

Future<void> init() async {
if (!_initialized) {
  // For iOS request permission first.
  _firebaseMessaging.requestNotificationPermissions();
  _firebaseMessaging.configure();

  // For testing purposes print the Firebase Messaging token
  String token = await _firebaseMessaging.getToken();
  print("FirebaseMessaging token****: $token");

  _initialized = true;

  _firebaseMessaging.configure(
    onMessage: (Map<String, dynamic> message) async {
      print("onMessage: $message");
      print("FirebaseMessaging token: $token");
      print('hi');
      try {
        Navigator.pushAndRemoveUntil(
            navigatorKey.currentContext,
            MaterialPageRoute(
              builder: (context) => ChangeNotifierProvider(
                create: (context) => CategoryListViewModel(),
                child: CategoryListPage(),
              ),
            ),
            (Route<dynamic> route) => false);
      } catch (e) {
        print("Exeeee:::" + e.toString());
      }

      print("found");
    },
    onLaunch: (Map<String, dynamic> message) async {
      print("onLaunch: $message");
    },
    onResume: (Map<String, dynamic> message) async {
      print("onResume: $message");
    },
  );
}
类PushNotificationsManager{
PushNotificationsManager.uz();
factory PushNotificationsManager()=>\u实例;
静态最终PushNotificationsManager_实例=
PushNotificationsManager.uz();
最终FirebaseMessaging_FirebaseMessaging=FirebaseMessaging();
bool _initialized=false;
Future init()异步{
如果(!\u已初始化){
//对于iOS,请先请求权限。
_firebaseMessaging.requestNotificationPermissions();
_firebaseMessaging.configure();
//出于测试目的,打印Firebase消息传递令牌
String token=wait_firebaseMessaging.getToken();
打印(“FirebaseMessaging令牌****:$token”);
_初始化=真;
_firebaseMessaging.configure(
onMessage:(映射消息)异步{
打印(“onMessage:$message”);
打印(“FirebaseMessaging令牌:$token”);
打印(“hi”);
试一试{
Navigator.pushandremove直到(
navigatorKey.currentContext,
材料路线(
生成器:(上下文)=>ChangeNotifierProvider(
创建:(上下文)=>CategoryListViewModel(),
子项:CategoryListPage(),
),
),
(路由)=>false);
}捕获(e){
打印(“exeee::”+e.toString());
}
印刷品(“发现”);
},
onLaunch:(映射消息)异步{
打印(“onLaunch:$message”);
},
onResume:(映射消息)异步{
打印(“onResume:$message”);
},
);
}
}
}

当应用程序位于前台时,可以使用Flatter_local_notifications 3.0.2库添加通知。这提供了一个选项,可以在单击导航按钮时导航到特定页面

添加一个全局键以保持状态,并在收到消息时使用它获取当前上下文

 final GlobalKey<NavigatorState> navigatorKey =
  new GlobalKey<NavigatorState>();
为firebase的初始化声明如下

FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
并在init状态下添加以下代码

@override
void initState() {
super.initState();

_firebaseMessaging.requestNotificationPermissions();
_firebaseMessaging.configure();

var initializationSettingsAndroid =
    AndroidInitializationSettings('mipmap/ic_launcher');
var initializationSettingsIOs = IOSInitializationSettings();
var initSetttings = InitializationSettings(
    android: initializationSettingsAndroid, iOS: initializationSettingsIOs);

flutterLocalNotificationsPlugin.initialize(initSetttings,
    onSelectNotification: onSelectNotification);

// For testing purposes print the Firebase Messaging to

_firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    print("onMessage@@@: $message");
    String token = await _firebaseMessaging.getToken();
    print("FirebaseMessaging token****: $token");
    try {
      showNotification();
    } catch (e) {
      print("Exeeee:::" + e.toString());
    }
  },
  onLaunch: (Map<String, dynamic> message) async {
    PushNotificationsManager.navigationHandler(
        navigatorKey.currentContext, "Test");
  },
  onResume: (Map<String, dynamic> message) async {
    PushNotificationsManager.navigationHandler(
        navigatorKey.currentContext, "Test");
  },
);
}

可以在PushNotificationsManager.navigationHandler()中编写自己的自定义导航代码。

您所做的是正确的,但只做了一半。如果你想让它在应用程序打开/后台/关闭时工作,你还必须处理在所有其他条件下收到通知的时间。但是,为了导航,您需要上下文,但没有上下文。您可以使用全局键并执行此操作,也可以阅读本指南,以便在没有上下文的情况下轻松导航

使用get_it软件包设置导航服务,如下所示

locator.registerLazySingleton(() => NavigationService());
在PushNotification管理器中获取一个服务实例,如下所示

  final NavigationService _navigationService = locator<NavigationService>();
 _navigationService.navigateTo(CreatePostViewRoute);
是他们关于推送通知处理的指南
超级简单,开箱即用

您需要在onlaunch中编写以进行单击。@hasan当我进一步检查时,我看到上下文为空。如何获得全局上下文。我在主dart文件中添加了全局密钥,并且仍然使用null。请检查我的答案导航器密钥是否在gloabal中使用。我正在从navigator键获取当前上下文。这可能意味着当您尝试使用该键进行导航时,该键为空。你能在声明密钥的地方显示代码吗?
  final NavigationService _navigationService = locator<NavigationService>();
 _navigationService.navigateTo(CreatePostViewRoute);