Flutter Firebase修改邮箱/密码未同步Auth的问题及报错解决
问题解决:Flutter Firebase 资料更新不同步Auth及重新认证报错
核心问题分析
- 重新认证参数错误:你在重新认证时用了修改后的新邮箱
user.email,但重新认证必须使用用户当前登录的旧邮箱和密码,这直接导致了user-not-found错误。 - 未同步Firebase Auth:只更新了Firestore的用户数据,没有调用Firebase Auth的API更新邮箱/密码,导致Auth和数据库信息不一致。
- 错误处理不规范:
catchError没有返回对应Future类型的值,引发了Invalid argument(s) (onError)异常。 - 安全隐患:将用户密码存储在Firestore中,这违反了安全规范,Firebase Auth会管理用户密码,无需手动存储。
分步修复方案
1. 修复重新认证与同步Auth逻辑
修改user_controller.dart中的updateUserRecord方法,确保先完成重新认证,再同步更新Auth和Firestore:
Future<void> updateUserRecord(UserModel user, String currentPassword) async { final currentUser = FirebaseAuth.instance.currentUser; if (currentUser == null) return; // 重新认证必须用当前用户的旧邮箱+当前密码 final credential = EmailAuthProvider.credential( email: currentUser.email!, password: currentPassword ); try { // 完成重新认证 await currentUser.reauthenticateWithCredential(credential); // 同步更新Firebase Auth邮箱(如果有变更) if (user.email != currentUser.email) { await currentUser.updateEmail(user.email); } // 更新Firestore用户数据 await _db.collection('users').doc(user.uid).update(user.toJson()); } catch (error) { print(error.toString()); Get.snackbar('错误', error.toString()); } }
2. 移除Firestore中的密码存储
- 修改
UserModel,删除password字段,禁止在Firestore中存储密码。 - 在
EditProfile中,密码输入框改为让用户输入当前登录密码(仅用于重新认证),无需显示旧密码:
// EditProfile中替换原密码控制器 final currentPasswordController = TextEditingController();
3. 修正EditProfile的保存逻辑
保存时传入当前密码用于重新认证,而非新密码:
CustomButton( text: "save", onPressed: () async { if (!_formKey.currentState!.validate()) return; final user = UserModel( uid: userData.uid, email: email.text.trim(), name: name.text.trim(), ); // 传入当前密码输入框的值 await controller.updateUserData(user, currentPasswordController.text.trim()); Get.to(() => Profile()); }, buttonColor: AppColor.primaryColor, ),
4. 单独处理密码修改(优化)
如果需要支持密码修改,建议单独做入口,流程更清晰:
// UserController中新增密码修改方法 Future<void> updateUserPassword(String currentPassword, String newPassword) async { final currentUser = FirebaseAuth.instance.currentUser; if (currentUser == null) return; final credential = EmailAuthProvider.credential( email: currentUser.email!, password: currentPassword ); try { await currentUser.reauthenticateWithCredential(credential); await currentUser.updatePassword(newPassword); Get.snackbar('成功', '密码修改完成'); } catch (error) { Get.snackbar('错误', error.toString()); } }
关键注意事项
- 重新认证是修改邮箱/密码的必要步骤,必须使用用户当前的登录凭证(旧邮箱+当前密码)。
- Firebase Auth的用户信息和Firestore的用户数据必须同步更新,否则会出现登录异常。
- 永远不要在数据库中存储用户密码,Firebase Auth会安全管理密码哈希。
内容的提问来源于stack exchange,提问作者Ma Ba
相关产品推荐
相关产品推荐

