Firebase首次谷歌登录时未创建Firestore用户数据问题排查
Flutter Firebase谷歌登录:addNewUser未执行+DocumentSnapshot崩溃问题
问题现象
- 新用户登录后,Firebase认证面板可显示用户信息,但
addNewUser函数未向Firestore添加用户数据 - 首次登录时应用崩溃,报错:
StateError(Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist)
相关代码
谷歌登录代码
Future<UserCredential> signInWithGoogle() async { showDialog( context: context, builder: (context) { return const Center(child: CircularProgressIndicator()); }); final _auth = FirebaseAuth.instance; // Trigger the authentication flow final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); // Obtain the auth details from the request final GoogleSignInAuthentication? googleAuth = await googleUser?.authentication; // Create a new credential final credential = GoogleAuthProvider.credential( accessToken: googleAuth?.accessToken, idToken: googleAuth?.idToken, ); final UserCredential authResult = await _auth.signInWithCredential(credential); final user = authResult.user; if (authResult.additionalUserInfo!.isNewUser) { if (user != null) { await DbServices().addNewUser(FirebaseAuth.instance.currentUser!.uid); } } removeLoading(); // Once signed in, return the UserCredential return await FirebaseAuth.instance.signInWithCredential(credential); } removeLoading() { return Navigator.of(context).pop(); } }
addNewUser函数
Future addNewUser(useruid) async { int heartid = await updateHeartId(); print('updated Heart Id $heartid....................'); await usersCollection.doc(useruid).set({ 'user name': FirebaseAuth.instance.currentUser!.displayName, 'uid': useruid, 'heartId': heartid, 'total hearts': 0, 'ringed': false, 'Timestamp': FieldValue.serverTimestamp(), 'profile pic': '', 'todayRinged': false, 'ringedDay': DateTime.now().day, }); }
问题原因与修复方案
1. addNewUser未执行的原因
登录流程最后重复调用了await FirebaseAuth.instance.signInWithCredential(credential),这会重新执行一次登录操作,第二次登录时additionalUserInfo!.isNewUser会变为false,直接跳过addNewUser的执行逻辑。
修复:
直接返回第一次登录获取的authResult,删除重复的登录调用:
// 替换原return语句 return authResult;
同时,可将FirebaseAuth.instance.currentUser!.uid替换为已获取的user.uid,避免不必要的空值风险:
await DbServices().addNewUser(user.uid);
2. DocumentSnapshot崩溃的原因
崩溃报错指向读取不存在的文档字段,大概率是updateHeartId函数内部读取Firestore文档时,直接访问了未定义的字段(比如使用doc.get('some_field')但未处理字段不存在的情况)。
修复:
检查updateHeartId函数实现,确保读取字段时处理字段不存在的场景:
- 使用
get方法的默认值参数:doc.get('heartId', defaultValue: 0) - 先判断字段存在性:
doc.exists && doc.data()!.containsKey('heartId')再读取字段
另外,addNewUser中FirebaseAuth.instance.currentUser!.displayName可能为空(谷歌用户可能未设置昵称),建议添加空值处理:
'user name': FirebaseAuth.instance.currentUser?.displayName ?? '匿名用户',
内容的提问来源于stack exchange,提问作者Xone
相关产品推荐
相关产品推荐

