You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Firebase修改邮箱/密码未同步Auth的问题及报错解决

问题解决:Flutter Firebase 资料更新不同步Auth及重新认证报错

核心问题分析

  1. 重新认证参数错误:你在重新认证时用了修改后的新邮箱user.email,但重新认证必须使用用户当前登录的旧邮箱和密码,这直接导致了user-not-found错误。
  2. 未同步Firebase Auth:只更新了Firestore的用户数据,没有调用Firebase Auth的API更新邮箱/密码,导致Auth和数据库信息不一致。
  3. 错误处理不规范:catchError没有返回对应Future类型的值,引发了Invalid argument(s) (onError)异常。
  4. 安全隐患:将用户密码存储在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:05:54