You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:39:15