提供程序(Flutter)包的异步异常处理(Firebase)

时间:2020-03-19 19:59:13

标签: firebase flutter exception dart flutter-provider

1。问题

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

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

当前,我基本上将ChangeNotifierProvider用于所有内容,但应该更改为FutureProvider动态。如果是这样,最好的方法是什么?


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

2。代码

2.1完整代码(可选)

目前,项目中的完整代码有些长,但是我认为下面显示的内容就足够了。

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

相关文件为:

  • firebase_auth.dart:带有相关数据的provider类。
  • login_screen.dartemail_field小部件通过provider数据馈给Consumer
  • password_reset_workflow.dart:通过LoginScreen将调用相关方法的按钮放入AnimatedSwitcher

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

1 个答案:

答案 0 :(得分:0)

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

notifyListeners()finally块内,将始终执行finally,无论是否发生错误,这就是总是调用notifyListeners()的原因。 / p>

此外,使用Future.delayed来同步事件是非常糟糕的,您应该为其构建另一个体系结构。