监听助手类中的变量变化

时间:2021-02-27 17:01:12

标签: firebase flutter asynchronous controller future

我正在尝试使用 firebase 为我的应用程序构建登录屏幕。我的登录功能工作正常,但如果登录失败,我在显示一些错误文本时遇到问题。

这是身份验证助手类的代码:

class AuthenticationService {

  final FirebaseAuth _firebaseAuth;

  String errorText = "";

  AuthenticationService(this._firebaseAuth);

  Stream<User> get authStateChanges => _firebaseAuth.authStateChanges();

  Future<void> signOut() async {
    await _firebaseAuth.signOut();
  }

  Future<String> signIn({String email, String password}) async {
    try {
      await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
      return "Signed in";
    }
    on FirebaseAuthException catch (e) {
      errorText = e.message;
      return e.message;
    }
  }

  Future<String> signUp({String email, String password}) async {
    try {
      await _firebaseAuth.createUserWithEmailAndPassword(email: email, password: password);
      signIn(email: email, password: password);
      return "Account created";
    }
    on FirebaseAuthException catch (e) {
      errorText = e.message;
      return e.message;
    }
  }
}

这是我的登录小部件的代码:

class SignIn extends StatefulWidget {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  @override
  State<StatefulWidget> createState() => _SignInWidgetState();
}

class _SignInWidgetState extends State<SignIn> {
  final TextEditingController errorController = TextEditingController();
  bool _isErrorContainerVisible = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sign In"),
      ),
      body: Column(
        children: [
          TextField(
            controller: widget.emailController,
            decoration: InputDecoration(
              labelText: "Email",
              hintText: "example@gmail.com",
              contentPadding: EdgeInsets.all(20.0),
            ),
          ),
          TextField(
            controller: widget.passwordController,
            obscureText: true,
            decoration: InputDecoration(
              labelText: "Password",
              hintText: "password",
              contentPadding: EdgeInsets.all(20.0),
            ),
          ),
          Visibility(
            child: Container(
              child: Text(
                errorController.text,
                style: TextStyle(
                  color: Colors.red,
                ),
              ),
              padding: const EdgeInsets.all(20.0),
            ),
            visible: _isErrorContainerVisible,
          ),
          RaisedButton(
            onPressed: () {
              context.read<AuthenticationService>().signIn(
                  email: widget.emailController.text.trim(),
                  password: widget.passwordController.text.trim());
            },
            child: Text("Sign In"),
          ),
          RaisedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) {
                  return SignUp(widget.emailController.text.trim().toString(),
                      widget.passwordController.text.trim().toString());
                }),
              );
            },
            child: Text("Sign Up"),
          )
        ],
      ),
    );
  }
}

基本上我想要做的是如果 Visibility 中的 errorText 有错误(因为用户登录失败),则在 AuthenticationService 小部件中显示文本。我意识到的问题是 signIn 方法是 Future ,因此不会立即设置错误(我想我需要某种变量的侦听器)。我遵循了一些使用 TextEditingController 的示例 here,除了我需要第二次单击登录按钮以显示错误而不是第一次出现错误之外,这还可以。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我最终找到了答案,并希望分享以备其他人需要帮助。

基本上,我需要让我的 AuthenticationHelper 类扩展一个 ChangeNotifier,它允许我在发生任何 firebase 身份验证异常时调用 notifyListeners()

接下来,我需要使用 Provider 库来创建一个 context.select(documentation),它允许我观察 notifyListeners() 何时被调用。一旦检测到错误文本发生更改,我将 _isErrorContainerVisible 设置为 true 并显示错误。

相关问题