dev*_*ock 8 firebase-authentication flutter gorouter flutter-navigation flutter-go-router
在我的 Flutter 应用程序中,我使用该go_router包来管理路由和Firebase Authentication用户身份验证。我有几个屏幕需要用户经过身份验证才能访问,例如帐户管理、交易和详细信息。
目前,我已经实现了重定向,go_router以确保未经身份验证的用户被正确重定向。但是,当用户已经位于这些屏幕之一并注销或会话过期时,我面临着挑战。
我正在考虑使用 BlocListener 来检测每个屏幕上身份验证状态的变化,但这似乎会导致代码重复。由于 Firebase 身份验证,我还有一个 Stream 通知身份验证状态的更改,并更新变量contex.isUserSignIn。
使用 go_router 和 Firebase 身份验证有效处理 Flutter 中的注销或会话过期事件的最佳实践是什么?
小智 9
我\xe2\x80\x99一直在努力解决完全相同的问题,并研究了几种替代方案和选项。
\nTL;DR: 选项 3 是我的首选,它使用该级别GoRouter.refresh()的方法main()根据 auth 流中的事件动态更新 GoRouter 状态。
请参阅此处的示例:https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/async_redirection.dart
\n这将顶层应用程序包装起来,通常MyApp(由main()in返回runApp())在 InheritedNotifer 小部件中,它们调用该小部件并在通知程序和 go_router 的解析管道StreamAuthScope之间创建依赖关系。当身份验证状态发生变化时(通过via进行通信) StreamAuthNotifier,这将依次重建MyApp(或App在示例中)。StreamAuthNotifiernotifyListeners()
我基于 Provider 包实现了一个类似的模型,其中ChangeProviderNotifier替换StreamAuthScope并包装MyApp了main(). Provider.of<>然而,这不允许在机柜内创建受监控的\xe2\x80\x99 GoRouter( redirect: )。为了解决这个问题,我创建了一个getRouter传入的函数,该函数在函数主体中但在函数之前isUserSignIn通过 a 进行监视。这可行,但感觉很麻烦,并且\n导致每次身份验证状态更改时都需要重建主程序。如果需要,我\xe2\x80\x99m确信你可以用 BLoC 模型代替 Provider 做类似的事情。Provider.of<>MyAppbuildMyApp
GoRouter\xe2\x80\x99srefreshListenable:参数这是基于此 go_router redirection.dart 示例:https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/redirection.dart
\n在您提到的问题中,您有一个通知身份验证状态更改的流。您可以将其包装在一个类中以extends ChangeNotifier使其可监听。然后在构造函数中,您可以使用 实例化和监视流,并在每次身份验证状态更改时(可能每次有流事件时).listen在附件中发出 a 。notifyListerners()在我的例子中,我调用这个类,AuthNotifier然后可以将其用作可听的GoRouter\xe2\x80\x99srefreshListenable:参数,如下所示:refreshListenable: AuthNotifier()
示例AuthNotifier类
class AuthNotifier extends ChangeNotifier {\n AuthNotifier() {\n // Continuously monitor for authStateChanges\n // per: https://firebase.google.com/docs/auth/flutter/start#authstatechanges\n _subscription =\n FirebaseAuth.instance.authStateChanges().listen((User? user) {\n // if user != null there is a user logged in, however\n // we can just monitor for auth state change and notify\n notifyListeners();\n });\n } // End AuthNotifier constructor\n\n late final StreamSubscription<dynamic> _subscription;\n\n @override\n void dispose() {\n _subscription.cancel();\n super.dispose();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n注意:为了避免创建和监视多个流,您需要确保此构造函数仅在您的应用程序中调用一次(在本例中作为GoRouter\xe2\x80\x99s的一部分refreshListenable:),或者将其修改为单例。
GoRouter\xe2\x80\x99s.refresh()方法与选项 2 类似但更直接的方法是使用GoRouter\xe2\x80\x99s.refresh()方法。notifyListerners()这直接调用刷新GoRouter配置的内部。我们可以使用与上面类似的类AuthNotifier,但我们不需要\xe2\x80\x99 extends ChangeNotifier,并且会调用router.refresh()来代替notifyListeners(),router你的GoRouter()配置在哪里。这个新类将在 中实例化main()。
鉴于其如此简单(2-3行代码),我们也可以跳过类定义和实例化,直接在主体中实现功能main(),如下所示:
Future<void> main() async {\n WidgetsFlutterBinding.ensureInitialized();\n await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);\n\n // Listen for Auth changes and .refresh the GoRouter [router]\n FirebaseAuth.instance.authStateChanges().listen((User? user) {\n router.refresh();\n });\n\n runApp(\n const MyApp(),\n );\n}\nRun Code Online (Sandbox Code Playgroud)\n由于这似乎是最直接、最简单的解决方案,因此它是我首选的解决方案,也是我已经实施的解决方案。然而,那里有很多令人困惑和过时的信息,我不\xe2\x80\x99觉得我有足够的经验来声称它是任何类型的“最佳实践”,所以将其留给其他人来判断和评论。
\n我希望所有这些对您和其他人有所帮助,因为它\xe2\x80\x99s花了我很长时间来制定这些不同的选项,并涉足广泛的材料和选项。我觉得绝对有机会改进这方面的官方 go_router 文档!
\n| 归档时间: |
|
| 查看次数: |
2293 次 |
| 最近记录: |