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

Firebase Google登录:如何判断用户是否已存在并自动跳转首页

问题

我想在用户通过Google登录时检查该用户是否已存在于Firebase中。我的应用里用户注册时会调用signInWithGoogle方法,代码如下:

Future<User?> signInWithGoogle() async {
  await Firebase.initializeApp();

  User? user;

  if (kIsWeb) {
    GoogleAuthProvider authProvider = GoogleAuthProvider();

    try {
      final UserCredential userCredential =
          await _auth.signInWithPopup(authProvider);

      user = userCredential.user;
    } catch (e) {
      print(e);
    }
  } else {
    try {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      final GoogleSignInAccount? googleSignInAccount =
          await googleSignIn.signIn().catchError((onError) => print(onError));
      ;

      if (googleSignInAccount != null) {
        final GoogleSignInAuthentication googleSignInAuthentication =
            await googleSignInAccount.authentication;

        final AuthCredential credential = GoogleAuthProvider.credential(
          accessToken: googleSignInAuthentication.accessToken,
          idToken: googleSignInAuthentication.idToken,
        );

        try {
          final UserCredential userCredential =
              await _auth.signInWithCredential(credential);

          user = userCredential.user;
        } on FirebaseAuthException catch (e) {
          if (e.code == 'account-exists-with-different-credential') {
            print('The account already exists with a different credential.');
          } else if (e.code == 'invalid-credential') {
            print('Error occurred while accessing credentials. Try again.');
          }
        } catch (e) {
          print(e);
        }
      }
    } catch (e) {
      print(e);
    }
  }

  if (user != null) {
    uid = user.uid;
    name = user.displayName;
    userEmail = user.email;
    imageUrl = user.photoURL;

    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool('auth', true);
    prefs.setString('id', user.uid);
    prefs.setString('name', user.displayName!);
  }

  return user;
}

但这个方法无法区分用户是新注册还是已存在的老用户,我需要在Google登录后判断:如果是老用户则自动跳转首页,新用户则继续完成注册流程。请问该如何实现?

解决方案

核心是利用Firebase返回的UserCredential对象中的additionalUserInfo.isNewUser属性,这个属性会直接告诉你当前登录的用户是否是首次创建账号。

修改后的代码(支持区分新/老用户)

我们可以修改方法的返回值,同时返回用户对象和是否为新用户的状态:

// 使用Dart 3.0+的记录类型返回结果
Future<({User? user, bool isNewUser})> signInWithGoogle() async {
  await Firebase.initializeApp();

  User? user;
  bool isNewUser = false;

  if (kIsWeb) {
    GoogleAuthProvider authProvider = GoogleAuthProvider();

    try {
      final UserCredential userCredential =
          await _auth.signInWithPopup(authProvider);

      user = userCredential.user;
      // 标记是否为新用户
      isNewUser = userCredential.additionalUserInfo?.isNewUser ?? false;
    } catch (e) {
      print(e);
    }
  } else {
    try {
      final GoogleSignIn googleSignIn = GoogleSignIn();

      final GoogleSignInAccount? googleSignInAccount =
          await googleSignIn.signIn().catchError((onError) => print(onError));

      if (googleSignInAccount != null) {
        final GoogleSignInAuthentication googleSignInAuthentication =
            await googleSignInAccount.authentication;

        final AuthCredential credential = GoogleAuthProvider.credential(
          accessToken: googleSignInAuthentication.accessToken,
          idToken: googleSignInAuthentication.idToken,
        );

        try {
          final UserCredential userCredential =
              await _auth.signInWithCredential(credential);

          user = userCredential.user;
          // 标记是否为新用户
          isNewUser = userCredential.additionalUserInfo?.isNewUser ?? false;
        } on FirebaseAuthException catch (e) {
          if (e.code == 'account-exists-with-different-credential') {
            print('该账号已通过其他方式注册。');
          } else if (e.code == 'invalid-credential') {
            print('获取凭证出错,请重试。');
          }
        } catch (e) {
          print(e);
        }
      }
    } catch (e) {
      print(e);
    }
  }

  if (user != null) {
    uid = user.uid;
    name = user.displayName;
    userEmail = user.email;
    imageUrl = user.photoURL;

    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool('auth', true);
    prefs.setString('id', user.uid);
    prefs.setString('name', user.displayName!);
  }

  return (user: user, isNewUser: isNewUser);
}

调用方法并处理跳转

在调用signInWithGoogle的地方,根据返回的isNewUser状态处理逻辑:

void handleGoogleSignIn() async {
  final result = await signInWithGoogle();
  if (result.user != null) {
    if (result.isNewUser) {
      // 新用户:继续完成注册流程
      Navigator.pushNamed(context, '/complete-registration');
    } else {
      // 老用户:直接跳转首页
      Navigator.pushReplacementNamed(context, '/home');
    }
  }
}

注意事项

  • additionalUserInfo?.isNewUser可能为null,所以用?? false兜底,确保逻辑不会出错。
  • 如果用户之前通过其他方式(如邮箱密码)注册过同一邮箱,Firebase会抛出account-exists-with-different-credential错误,你可以在catch块中处理这种场景,比如提示用户改用原登录方式。

内容的提问来源于stack exchange,提问作者Cidiko Andorem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:48:17