首页 > 解决方案 > 使用 Provider (Flutter) 包进行异步异常处理 (Firebase)

问题描述

1.问题

我在我的应用程序的简单身份验证包中使用try-catch-finally1动态来处理 Firebase 的异常处理。在其中,当我从 Firebase 的身份验证服务收到错误时,我会更新labelText(自定义)上的TextFormField以向用户显示发生了错误。

但是,notifyListeners()显然与catch子句同时运行,导致重建不会与异常处理同步发生。

目前,我ChangeNotifierProvider基本上都在使用,但我应该改成FutureProvider动态的。如果是这样,最好的方法是什么?


1我也尝试过使用 then-catchError-whenComplete

2. 守则

2.1 完整代码(可选)

在项目的这一点上,完整的代码有点长,但我认为下面显示的内容就足够了。

无论如何,如果您想检查所有内容,整个项目都可用:flutter_firebase_auth_benchmark

相关文件为:

2.2 提供者类

我必须使用Future.delayed才能手动同步notifyListeners()build()方法 - 我知道,我知道,这非常糟糕......

class Auth extends ChangeNotifier {
  String _errorMsg;

  String get errorMsg => _errorMsg;

  ...

  Future<void> sendPasswordResetWithEmail({@required String email}) async {
    try {
      await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
    } catch(e) {
      switch (e.code) {
        case 'ERROR_USER_NOT_FOUND':
          _errorMsg = 'user not found';
          break;
        default:
          throw UnknownPasswordResetError(
              'Unknown error for password reset with Firebase.');
      }
    } finally {
      notifyListeners();
      await Future.delayed(Duration(milliseconds: 10));
    }
  }
}

2.3 我的自定义TextFormField小部件

像这样的东西在应用程序中:

return Consumer<Auth>(
  builder: (context, auth, _) {
    return AuthTextFormField(
      ...,
      errorMsgFromServer: auth.errorMsg,
    );
  }
);

formKey.currentState.validate()最后,在子句中使用验证按钮if来异步触发await auth.sendPasswordResetWithEmail

标签: firebaseflutterexceptiondartflutter-provider

解决方案


notifyListeners() 显然与 catch 子句同时运行

notifyListeners()在一个finally块内finally,无论是否有错误,总是会被执行,这就是为什么notifyListeners()总是被调用。

此外,Future.delayed用于同步事件非常糟糕,您应该为其创建另一个架构。


推荐阅读