如何修复手机号认证后Firebase Storage提示user unauthenticated的问题
问题根因
cloud_firestore/not-found报错:Firebase Auth创建账号仅会生成认证用户记录,不会自动在Firestore的users集合中生成对应UID的文档。你当前代码中调用的get()获取文档、update()更新文档两个操作,都要求目标文档已提前存在,从未创建过的文档自然会触发不存在报错。firebase_storage/unauthenticated报错:通常是手机号注册完成后,你没有等待Auth状态同步完成就触发了资料更新逻辑,此时firebaseAuth.currentUser还未赋值,请求Storage时没有携带用户认证凭证。
你的Firestore和Storage安全规则配置符合当前需求,不需要调整。
修复步骤
1. 改造资料更新方法,兼容文档不存在的场景
将最终更新文档的update方法改为带merge参数的set方法,文档不存在时会自动创建,存在时会合并更新字段,同时补充文档不存在时的初始化逻辑,避免解析空数据报错:
String currentUid() { // 新增非空断言,调用该方法时必须保证用户已登录 return firebaseAuth.currentUser!.uid; } updateProfile( {File? image, String? username, String? email, String? sex, String? dob, String? phone}) async { final uid = currentUid(); final docRef = usersRef.doc(uid); DocumentSnapshot doc = await docRef.get(); UserModel users; // 判断文档是否存在,不存在则初始化空模型 if (doc.exists) { users = UserModel.fromJson(doc.data() as Map<String, dynamic>); } else { users = UserModel(); } // 赋值逻辑保持不变 if (username != null) users.username = username; if (email != null) users.email = email; if (phone != null) users.phone = phone; if (dob != null) users.dob = dob; if (sex != null) users.sex = sex; if (image != null) { users.photoUrl = await uploadImage(profilePic, image); } // 改用set+merge模式,兼容创建、更新两种场景 await docRef.set({ 'username': users.username, 'photoUrl': users.photoUrl, 'phone': users.phone, 'dob': users.dob, 'email': users.email, 'sex': users.sex }, SetOptions(merge: true)); return true; }
2. 修复未认证报错
触发updateProfile前先确认认证状态已同步,不要在注册完成回调中立刻调用资料更新逻辑,建议监听Auth状态流,确认用户登录完成后再进入资料编辑页面:
// 示例:监听认证状态,用户登录完成后再跳转编辑页 firebaseAuth.authStateChanges().listen((user) { if (user != null) { Navigator.push(context, MaterialPageRoute(builder: (context) => EditProfilePage())); } });
可选优化
如果业务需要用户注册后就有默认的用户字段,可以在注册成功的回调中,先为该UID创建一条初始化的用户文档,后续编辑可直接使用update方法。
另外可额外检查usersRef指向的集合路径是否和安全规则中的/users/{id}完全一致,注意大小写敏感,避免路径拼写错误导致的找不到文档问题。
内容的提问来源于stack exchange,提问作者HaKim
相关产品推荐
相关产品推荐

