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

Flutter集成Firebase:Google登录后Firestore的displayName存为null如何解决?

Google登录后Firestore中displayName字段为null的问题修复

问题场景

我用Flutter+Firebase开发应用,通过Firebase Auth的Google登录实现首次登录时创建用户档案,代码如下:

void _handleGoogleSignIn() async {
    try {
      GoogleAuthProvider googleAuthProvider = GoogleAuthProvider();
      UserCredential userCredential =
          await _auth.signInWithProvider(googleAuthProvider);
      User? user = userCredential.user;

      // 检查用户档案是否存在
      if (user != null) {
        DocumentSnapshot userDoc = await FirebaseFirestore.instance
            .collection("users")
            .doc(user.uid)
            .get();

        // 不存在则创建
        if (!userDoc.exists) {
          await FirebaseFirestore.instance
              .collection("users")
              .doc(user.uid)
              .set(
            {
              "photoUrl": user.photoURL,
              "displayName": user.displayName,
              "email": user.email,
            },
          );
        }
      }
    } catch (e) {
      showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            content: Text(e.toString()),
          );
        },
      );
    }
  }

但在Firestore控制台中发现displayName字段始终为null,请问问题出在哪,怎么修复?


原因及修复方案

1. 未请求必要的权限范围

GoogleAuthProvider默认可能未请求完整的用户信息权限,导致返回的User对象缺少displayName等字段。需要显式添加email和profile权限:

GoogleAuthProvider googleAuthProvider = GoogleAuthProvider()
  ..addScope('email')
  ..addScope('profile');

2. 未刷新用户信息

首次登录返回的User对象可能未包含完整数据,调用reload()刷新后再获取最新用户信息:

User? user = userCredential.user;
if (user != null) {
  await user.reload();
  // 重新获取更新后的用户对象
  user = FirebaseAuth.instance.currentUser;
}

3. 从additionalUserInfo获取更可靠的数据

UserCredential中的additionalUserInfo.profile包含Google返回的原始用户数据,比User对象的字段更稳定,可以作为备选来源:

final userProfile = userCredential.additionalUserInfo?.profile;
final displayName = userProfile?['name'] ?? user?.displayName;
final photoUrl = userProfile?['picture'] ?? user?.photoURL;

完整修复后的代码

void _handleGoogleSignIn() async {
    try {
      // 添加权限范围
      GoogleAuthProvider googleAuthProvider = GoogleAuthProvider()
        ..addScope('email')
        ..addScope('profile');
        
      UserCredential userCredential =
          await _auth.signInWithProvider(googleAuthProvider);
      User? user = userCredential.user;

      if (user != null) {
        // 刷新用户信息
        await user.reload();
        user = FirebaseAuth.instance.currentUser;
        
        // 从additionalUserInfo获取备选数据
        final userProfile = userCredential.additionalUserInfo?.profile;
        final displayName = userProfile?['name'] ?? user?.displayName;
        final photoUrl = userProfile?['picture'] ?? user?.photoURL;
        final email = user?.email;

        DocumentSnapshot userDoc = await FirebaseFirestore.instance
            .collection("users")
            .doc(user.uid)
            .get();

        if (!userDoc.exists && displayName != null && email != null) {
          await FirebaseFirestore.instance
              .collection("users")
              .doc(user.uid)
              .set({
                "photoUrl": photoUrl,
                "displayName": displayName,
                "email": email,
              });
        }
      }
    } catch (e) {
      showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            content: Text(e.toString()),
          );
        },
      );
    }
  }

内容的提问来源于stack exchange,提问作者GN Vageesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:04:53