Flutter Google登录成功后无法自动跳转到底部导航栏页面
问题分析
登录成功后无法自动跳转至BottomNavigationBarPage,仅点击返回按钮可见,核心原因可能是:
ChangeNotifierProvider层级过低,导致状态变化无法正确触发页面重建- 登录流程中异步操作的时序问题,未确保认证状态更新后再完成状态通知
StreamBuilder未正确监听Firebase认证状态的变化
解决方案
1. 调整Provider层级
将ChangeNotifierProvider移至MaterialApp外层,确保全局状态可被所有页面正确监听:
修改main.dart的build方法:
@override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => GoogleSignInProvider(), child: MaterialApp( title: 'appTitle', home: const CheckIsLogged(), ), ); }
同时移除CheckIsLogged内部的ChangeNotifierProvider:
class CheckIsLogged extends StatelessWidget { const CheckIsLogged({Key? key}) : super(key: key); @override Widget build(BuildContext context) => Scaffold( body: StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { final provider = Provider.of<GoogleSignInProvider>(context); if (provider.isSigningIn) { return const Center( child: CircularProgressIndicator(color: primaryColor)); } else if (snapshot.hasData) { return const BottomNavigationBarPage(); } else { return const FirstPage(); } }, ), ); }
2. 优化登录方法的异步流程
将登录方法中的回调改为await,确保认证状态完全更新后再修改加载状态,避免时序问题:
修改GoogleSignInProvider的login方法:
Future login() async { isSigningIn = true; final user = await googleSignIn.signIn(); if (user == null) { isSigningIn = false; return; } final googleAuth = await user.authentication; final credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); // 确保认证完成,Firebase状态更新 await FirebaseAuth.instance.signInWithCredential(credential); // 用await替代then,避免回调嵌套导致的时序问题 var db = Mysql(); var conn = await db.getConnection(); uid = FirebaseAuth.instance.currentUser?.email; debugPrint('User ID: $uid'); String sql = 'select uid from users where uid = "$uid"'; var results = await conn.query(sql); userAlready = ''; for (var row in results) { userAlready = row[0].toString(); } if (userAlready != uid) { debugPrint('Is empty...'); debugPrint('User Saving :' + uid!); String insertSql = 'insert into users (uid) values ("$uid")'; await conn.query(insertSql); } else { debugPrint('Is not empty...'); debugPrint('User Already Saved :' + userAlready); } // 所有操作完成后再关闭加载状态 isSigningIn = false; }
3. 验证StreamBuilder状态监听
在CheckIsLogged的StreamBuilder中添加日志,确认认证状态变化是否被正确捕获:
builder: (context, snapshot) { debugPrint('认证状态:${snapshot.connectionState},是否有用户:${snapshot.hasData}'); final provider = Provider.of<GoogleSignInProvider>(context); // ... 原有逻辑 }
登录成功后,控制台应输出认证状态:Active,是否有用户:true,此时StreamBuilder会自动切换至BottomNavigationBarPage。
内容的提问来源于stack exchange,提问作者DLC
相关产品推荐
相关产品推荐

