Flutter Google登录未选择账号仍跳转首页Bug问题求助
问题根因
- 登录按钮调用时误用了Dart级联运算符
..:..catchError不会等待异步执行结果,直接返回Future对象本身,导致后续if (result == null) return的判断完全失效,无论登录结果如何都会执行跳转首页的逻辑。 signInWithGoogle方法没有明确返回值:仅在用户取消选择账号时返回null,登录成功分支没有返回任何有效对象,方法默认返回null,外层无法通过返回值判断登录是否成功。- main.dart路由配置冲突:同时设置了
initialRoute和home属性,home优先级高于初始路由,会导致路由栈状态混乱,跳转逻辑不受控。 - 存在冗余代码:重复获取了两次
GoogleSignInAuthentication,容易引发状态判断异常。
修复方案
1. 修正登录按钮的调用逻辑
移除错误的级联调用写法,正确等待异步返回结果,空值判断生效后再做跳转:
ElevatedButton.icon( style: ElevatedButton.styleFrom( primary: Colors.white, onPrimary: Colors.black, minimumSize: const Size(double.infinity, 50), ), icon: const FaIcon(FontAwesomeIcons.google, color: Colors.red), label: const Text("Login using Gmail"), onPressed: () async { try { // 不要使用..级联运算符,直接await方法返回结果 final loginResult = await FirebaseServices().signInWithGoogle(); // 返回值为null代表用户取消登录/登录失败,直接返回不跳转 if (loginResult == null) return; // 登录成功后用pushReplacement替换路由,避免返回键回到登录页 Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const HomePage()) ); } on FirebaseAuthException catch (e) { print(e.message); Fluttertoast.showToast(msg: e.message ?? "登录失败,请重试"); } catch (e) { print(e.toString()); Fluttertoast.showToast(msg: "登录出现异常,请重试"); } }, )
2. 重构signInWithGoogle方法,明确所有分支的返回值
移除冗余逻辑,保证用户取消、登录失败、登录成功三个场景都返回明确的结果:
class FirebaseServices{ final _auth = FirebaseAuth.instance; final _googleSignIn = GoogleSignIn(); // 明确返回值类型:登录成功返回UserCredential,其余场景返回null Future<UserCredential?> signInWithGoogle() async { try { // 唤起谷歌账号选择弹窗 final GoogleSignInAccount? googleSignInAccount = await _googleSignIn.signIn(); // 用户点击外部/返回键关闭弹窗、取消选择时直接返回null if (googleSignInAccount == null) return null; // 一次性获取谷歌认证信息 final GoogleSignInAuthentication googleSignInAuth = await googleSignInAccount.authentication; // 生成Firebase登录凭证 final AuthCredential authCredential = GoogleAuthProvider.credential( accessToken: googleSignInAuth.accessToken, idToken: googleSignInAuth.idToken ); // 完成Firebase登录 final UserCredential credential = await _auth.signInWithCredential(authCredential); // 同步用户信息到Firestore await postDetailsToFirestore(); // 登录成功返回凭证 return credential; } on FirebaseAuthException catch (e) { print(e.message); Fluttertoast.showToast(msg: e.message ?? "谷歌登录失败"); return null; } catch (e) { print(e.toString()); Fluttertoast.showToast(msg: "登录过程出现异常"); return null; } } // signOut、postDetailsToFirestore方法无需修改,保持原有逻辑即可 signOut() async{ await _auth.signOut(); await _googleSignIn.signOut(); } postDetailsToFirestore() async{ FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance; User? user = _auth.currentUser; UserModel userModel = UserModel(); userModel.email = user!.email; userModel.uid = user.uid; userModel.fullname = user.displayName; userModel.profileimage = user.photoURL; await firebaseFirestore .collection("Users") .doc(user.uid) .set(userModel.toMap()); } }
3. 修复main.dart路由冲突
移除重复的home配置,通过auth状态监听自动做路由跳转,避免初始路由判断失效:
class _MyAppState extends State<MyApp> { late StreamSubscription<User?> authSub; @override void initState() { super.initState(); authSub = FirebaseAuth.instance.authStateChanges().listen((user) { if (user == null) { print('User is currently signed out!'); Get.offAllNamed(LoginPage.id); } else { print('User is signed in!'); Get.offAllNamed(HomePage.id); } }); } @override void dispose() { authSub.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return GetMaterialApp( // 移除home属性,避免和路由配置冲突 initialRoute: LoginPage.id, routes: { LoginPage.id: (context) => const LoginPage(), HomePage.id: (context) => const HomePage(), }, ); } }
验证要点
修复后测试以下场景,均不会再异常跳转到首页:
- 点击账号选择弹窗外部关闭弹窗
- 按系统返回键关闭账号选择弹窗
- 选择账号后认证失败
- 网络异常导致登录流程中断
内容的提问来源于stack exchange,提问作者Frederick Alinday
相关产品推荐
相关产品推荐

