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
相关产品推荐
相关产品推荐

