在 Flutter 中哪里处理 Firebase 动态链接?

Where to handle Firebase Dynamic Links in Flutter?

我使用 Firebase 动态 links 和命名路由。我想要的是为动态 link 事件安装一个全局侦听器,并在提供令牌时转发到注册页面。在下面的代码中,我得到了异常 The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.,这意味着我必须将导航代码放在 MaterialApp 的 home: 属性 下方。但是在执行此操作时,我必须为 earch 路由实现动态 links 事件处理程序。

class MyApp extends StatelessWidget {
  String title = "Framr";

  @override
  Widget build(BuildContext context) {

    FirebaseDynamicLinks.instance.onLink(
      onSuccess: (linkData) {
        if (linkData != null) {
          try {
            Navigator.pushNamed(context, '/register', arguments: linkData);
            // throws: The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
          } catch(e) {
            print(e);
          }
        }
        return null;
      }
    );

    return MaterialApp(
      title: "...",
      home: LoginPage(),
      routes: {
        '/createEvent': (context) => CreateEventPage(),
        '/showEvent': (context) => ShowEventPage(),
        '/register': (context) => RegisterPage(),
      },
    );
  }
}

我能够按照动态 link README with the use of the no_context_navigation package or GlobalKey to workaround around the lack of context to call Navigator.pushNamed(...). Note: You don't have to use no_context_navigation. You can implement the no context routing yourself. Here's an example.

提供的示例完成这项工作
// Add this
import 'package:no_context_navigation/no_context_navigation.dart';

void main() {
  runApp(MaterialApp(
    title: 'Dynamic Links Example',
    // Add this
    navigatorKey: NavigationService.navigationKey,
    routes: <String, WidgetBuilder>{
      '/': (BuildContext context) => MyHomeWidget(), // Default home route
      '/helloworld': (BuildContext context) => MyHelloWorldWidget(),
    },
  ));
}

class MyHomeWidgetState extends State<MyHomeWidget> {
  .
  .
  .
  @override
  void initState() {
    super.initState();
    this.initDynamicLinks();
  }

  void initDynamicLinks() async {
    FirebaseDynamicLinks.instance.onLink(
      onSuccess: (PendingDynamicLinkData dynamicLink) async {
        // Add this.
        final NavigationService navService = NavigationService();
        final Uri deepLink = dynamicLink?.link;

        if (deepLink != null) {
          // This doesn't work due to lack of context
          // Navigator.pushNamed(context, deepLink.path);
          
          // Use this instead
          navService.pushNamed('/helloworld', args: dynamicLink);
        }
      },
      onError: (OnLinkErrorException e) async {
        print('onLinkError');
        print(e.message);
      }
    );
    
    final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
    final Uri deepLink = data?.link;

    if (deepLink != null) {
      // This doesn't work due to lack of context
      // Navigator.pushNamed(context, deepLink.path);
      
      // Use this instead
      navService.pushNamed('/helloworld', args: dynamicLink);
    }
  }
  .
  .
  .
}

// pubspec.yaml
no_context_navigation: ^1.0.4