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
在示例中)。StreamAuthNotifier
notifyListeners()
我基于 Provider 包实现了一个类似的模型,其中ChangeProviderNotifier
替换StreamAuthScope
并包装MyApp
了main()
. Provider.of<>
然而,这不允许在机柜内创建受监控的\xe2\x80\x99 GoRouter( redirect: )
。为了解决这个问题,我创建了一个getRouter
传入的函数,该函数在函数主体中但在函数之前isUserSignIn
通过 a 进行监视。这可行,但感觉很麻烦,并且\n导致每次身份验证状态更改时都需要重建主程序。如果需要,我\xe2\x80\x99m确信你可以用 BLoC 模型代替 Provider 做类似的事情。Provider.of<>
MyApp
build
MyApp
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}\n
Run 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}\n
Run Code Online (Sandbox Code Playgroud)\n由于这似乎是最直接、最简单的解决方案,因此它是我首选的解决方案,也是我已经实施的解决方案。然而,那里有很多令人困惑和过时的信息,我不\xe2\x80\x99觉得我有足够的经验来声称它是任何类型的“最佳实践”,所以将其留给其他人来判断和评论。
\n我希望所有这些对您和其他人有所帮助,因为它\xe2\x80\x99s花了我很长时间来制定这些不同的选项,并涉足广泛的材料和选项。我觉得绝对有机会改进这方面的官方 go_router 文档!
\n 归档时间: |
|
查看次数: |
2293 次 |
最近记录: |