Flutter Web中isSignedIn变量无法正确捕获用户登录状态
解决Flutter Web中Firebase Auth登录状态判断异常导致GoRouter跳转失败的问题
问题根源分析
你遇到的核心问题有三个:
- Stream监听方式错误:
authStateChanges()返回的是Stream,用await _auth.authStateChanges().listen(...)时,await等待的是Stream订阅完成,而非等待获取用户数据,导致_signedInCustomer()直接返回初始null,isSignedIn被设为false。 - GoRouter重定向逻辑错误:原代码中已登录时返回
/orders会触发无限重定向,GoRouter会不断尝试跳转该路径并重复执行redirect判断。 - 未触发状态更新:即使后续获取到用户数据,未调用
setState()更新状态,导致isSignedIn的值无法同步到路由逻辑中。
代码修正方案
1. 修正Auth状态获取逻辑
修改initState中的状态判断逻辑,直接获取当前用户并监听后续状态变化,同时通过setState()更新状态:
class _MyAppState extends State<MyApp> { final FirebaseAuth _auth = FirebaseAuth.instance; User? customer; bool? isSignedIn; @override void initState() { super.initState(); _initAuthState(); } // 初始化并监听Auth状态 Future<void> _initAuthState() async { // 先获取当前已登录用户 final currentUser = _auth.currentUser; setState(() { customer = currentUser; isSignedIn = currentUser != null; }); print('初始化isSignedIn = $isSignedIn'); // 监听后续Auth状态变化 _auth.authStateChanges().listen((User? user) { setState(() { customer = user; isSignedIn = user != null; }); print('用户状态更新: $user'); print('更新后isSignedIn = $isSignedIn'); }); } // 剩余代码省略... }
2. 修正GoRouter重定向逻辑
调整redirect逻辑,已登录时允许访问(返回null),未登录时跳转登录页,同时处理isSignedIn为null的初始化状态:
late final GoRouter _router = GoRouter( initialLocation: "/", routes: [ // 其他路由省略... GoRoute( name: "orders", path: "/orders", pageBuilder: (context, state) => CustomAnimatedNavigation(key: state.pageKey, child: MyOrders()), redirect: (context, state) { // 初始化状态时暂时不重定向 if (isSignedIn == null) return null; // 未登录且不在登录页,跳转登录 if (!isSignedIn!) { return state.location != '/signin' ? '/signin' : null; } // 已登录,允许访问当前页面 return null; }, ), ], );
关键说明
- 直接使用
_auth.currentUser可快速获取初始化时的登录状态,避免Stream监听的延迟问题。 - 通过
authStateChanges().listen()实时监听用户登录/登出状态变化,并用setState()更新状态,确保路由逻辑能感知到变化。 - 重定向逻辑中,已登录时必须返回
null,否则会触发无限循环跳转。
内容的提问来源于stack exchange,提问作者pbs
相关产品推荐
相关产品推荐

