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

Flutter Bloc登录按钮重复点击致邮箱密码值为空的问题求助

问题根源

你的SignInLoading、SignInSuccess、SignInError状态子类在实例化时,没有继承当前状态中的email和password值,而是使用了SignInState默认的空字符串初始化。例如当你调用emit(SignInError(error: "xxx"))时,新状态的email和password会被重置为空,导致后续读取状态时丢失之前输入的内容。

修改步骤

1. 更新状态子类的构造函数

让所有状态子类在构造时接收并传递父类的email、password、passwordVisible参数,确保状态切换时保留原有输入值:

class SignInState {
  String email;
  String password;
  bool passwordVisible;

  SignInState({
    this.email = "",
    this.password = "",
    this.passwordVisible = false,
  });

  List<Object> get props => [email, password, passwordVisible];

  SignInState copyWith({
    String? email,
    String? password,
    bool? passwordVisible,
  }) {
    return SignInState(
      email: email ?? this.email,
      password: password ?? this.password,
      passwordVisible: passwordVisible ?? this.passwordVisible,
    );
  }
}

class SignInLoading extends SignInState {
  SignInLoading({
    super.email,
    super.password,
    super.passwordVisible,
  });
}

class SignInSuccess extends SignInState {
  SignInSuccess({
    super.email,
    super.password,
    super.passwordVisible,
  });
}

class SignInError extends SignInState {
  final String error;

  SignInError({
    required this.error,
    super.email,
    super.password,
    super.passwordVisible,
  });

  @override
  List<Object> get props => [error, email, password, passwordVisible];
}

2. 在Bloc中emit状态时传递当前值

在处理登录事件时,emit错误或成功状态时,将当前state的email、password传递给子类构造:

on<SignInLoginButtonEvent>(
  (event, emit) async {
    final email = state.email;
    final password = state.password;

    print("Email is $email Password is $password");

    if (email.isEmpty) {
      emit(SignInError(
        error: "Please Enter Email",
        email: email,
        password: password,
      ));
      return; // 提前返回,避免后续执行无效逻辑
    } else if (password.isEmpty) {
      emit(SignInError(
        error: "Please Enter password",
        email: email,
        password: password,
      ));
      return;
    }
    try {
      final credential = await FirebaseAuth.instance
          .signInWithEmailAndPassword(email: email, password: password);

      if (credential.user == null) {
        emit(SignInError(
          error: "User Not Found",
          email: email,
          password: password,
        ));
        return;
      }
      if (!credential.user!.emailVerified) {
        emit(SignInError(
          error: "Email Not Verified",
          email: email,
          password: password,
        ));
        return;
      }
      if (credential.user != null) {
        emit(SignInSuccess(
          email: email,
          password: password,
        ));
      }
    } on FirebaseAuthException catch (e) {
      String errorMessage;
      switch (e.code) {
        case "user-not-found":
          errorMessage = "User Not Found";
          break;
        case "wrong-password":
          errorMessage = "Wrong Password";
          break;
        case "invalid-email":
          errorMessage = "Invalid Email";
          break;
        default:
          errorMessage = "Login Failed";
      }
      emit(SignInError(
        error: errorMessage,
        email: email,
        password: password,
      ));
    }
  },
);

额外优化说明

  • 在emit错误状态后添加return,避免后续代码继续执行,减少不必要的逻辑分支。
  • 给SignInError的props添加error字段,确保Bloc能正确识别状态变化。

修改完成后,无论状态如何切换(错误、成功、加载),都会保留用户之前输入的邮箱和密码值,解决点击两次登录按钮后值为空的问题,同时也能修复单独输入邮箱或密码后点击登录,另一个值丢失的问题。

内容的提问来源于stack exchange,提问作者Miraj Hossain Shawon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:26