Flutter/Dart中Firebase用户变量本地访问及数据存储问题咨询
解答
1. 修改AuthUser类及FirebaseAuthProvider实现正确映射
问题核心是你强制将可能为null的displayName等字段用!断言为非空,导致空指针错误;同时currentUser可能是本地缓存的旧数据,需要刷新才能获取最新字段值。
修改AuthUser类:
将可空字段改为String?类型,避免强制非空断言:
@immutable class AuthUser { final String id; final String email; final String? displayName; // 改为可空类型 final String? phoneNumber; final String? photoURL; final bool isEmailVerified; const AuthUser({ required this.id, required this.email, this.displayName, this.phoneNumber, this.photoURL, required this.isEmailVerified, }); factory AuthUser.fromFirebase(User user) => AuthUser( id: user.uid, email: user.email!, // 邮箱一般不会为null(匿名用户除外) displayName: user.displayName, phoneNumber: user.phoneNumber, photoURL: user.photoURL, isEmailVerified: user.emailVerified, ); }
修改FirebaseAuthProvider获取用户逻辑:
调用reload()刷新缓存,确保获取最新用户数据:
Future<AuthUser?> getCurrentUser() async { final user = FirebaseAuth.instance.currentUser; if (user != null) { await user.reload(); // 刷新用户数据 final refreshedUser = FirebaseAuth.instance.currentUser; // 重新获取刷新后的用户 return AuthUser.fromFirebase(refreshedUser!); } return null; }
2. 用户详细信息的存储选择
- Firebase Auth:适合存储核心身份字段,比如邮箱、手机号、displayName、photoURL、UID等,这些字段直接绑定用户身份,Auth提供内置的更新和验证机制,访问速度快,适合快速获取基础身份信息。
- Firestore:适合存储自定义详细信息,比如地址、生日、偏好设置等,因为Auth的字段数量有限,且Firestore支持更复杂的数据结构和查询,能灵活扩展用户信息。
总结:身份相关基础字段存在Firebase Auth,额外自定义数据存在Firestore,两者通过用户UID关联。
3. 优化注册流程确保信息正确存储
注册流程需要保证Auth用户创建、Auth字段更新、Firestore数据写入三步的一致性,避免出现Auth用户创建成功但Firestore数据写入失败的情况。
示例优化后的注册流程:
Future<void> registerUser({ required String email, required String password, required String displayName, required String address, // 额外信息 }) async { try { // 1. 创建Firebase Auth用户 final userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email, password: password, ); final user = userCredential.user; if (user == null) throw Exception("用户创建失败"); // 2. 更新Auth用户的displayName等字段 await user.updateDisplayName(displayName); // 如需设置头像,可调用user.updatePhotoURL("头像URL") // 3. 用事务将额外信息写入Firestore,确保原子性 await FirebaseFirestore.instance.runTransaction((transaction) async { final userDoc = FirebaseFirestore.instance.collection("users").doc(user.uid); await transaction.set(userDoc, { "displayName": displayName, "address": address, "createdAt": FieldValue.serverTimestamp(), }); }); // 4. 刷新用户信息,更新本地缓存 await user.reload(); } catch (e) { // 处理注册异常,比如邮箱已存在、密码不符合要求等 // 若Firestore写入失败,可考虑删除已创建的Auth用户 if (FirebaseAuth.instance.currentUser != null) { await FirebaseAuth.instance.currentUser!.delete(); } rethrow; } }
关键点:
- 使用Firestore事务确保数据写入的原子性,避免不一致;
- 注册完成后调用
user.reload()刷新本地缓存; - 异常处理覆盖全流程,必要时回滚Auth用户创建操作。
内容的提问来源于stack exchange,提问作者user17281101
相关产品推荐
相关产品推荐

