firebase - 使用 Provider (Flutter) 包进行异步异常处理 (Firebase)
问题描述
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.dart
:使用小部件email_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
。
解决方案
notifyListeners() 显然与 catch 子句同时运行
notifyListeners()
在一个finally
块内finally
,无论是否有错误,总是会被执行,这就是为什么notifyListeners()
总是被调用。
此外,Future.delayed
用于同步事件非常糟糕,您应该为其创建另一个架构。
推荐阅读
- c++ - 通过在类析构函数中重置成员shared_ptrs解决C++11 shared_ptr循环引用?
- lua - 使用 TweenInfo 时显示“TweenInfo.new 第一个参数需要一个时间数字”的错误消息
- python - Youtube 谷歌弹出窗口 - selenium
- html - 如何制作可供多人同时使用的 Flask 应用程序?
- python - re.finditer 没有找到子字符串
- ios - widgetURL 在 Foreach 内被覆盖?
- python - 打印序列的问题
- assembly - Lisp x86_64 编译器产生不正确的输出
- javascript - 在计算属性内的模板中使用 v-if 不起作用
- spring-boot - 如何让springboot注册一个RestController?