使用 Provider (Flutter) 包进行异步异常处理 (Firebase)
Posted
技术标签:
【中文标题】使用 Provider (Flutter) 包进行异步异常处理 (Firebase)【英文标题】:Async Exception-Handling (Firebase) with the Provider (Flutter) Package 【发布时间】:2020-07-01 00:05:20 【问题描述】:1。问题
我正在使用 try-catch-finally
1 动态来处理我的应用程序的简单身份验证包中的 Firebase 异常处理。在其中,当我收到来自 Firebase 身份验证服务的错误时,我会更新(自定义)TextFormField
上的 labelText
,以向用户显示发生了错误。
但是,notifyListeners()
显然是与 catch
子句同时运行的,导致重建不会与异常处理同步发生。
目前,我基本上都在使用ChangeNotifierProvider
,但我应该更改为FutureProvider
动态。如果是这样,最好的方法是什么?
1 我也尝试过使用then-catchError-whenComplete
。
2。守则
2.1 完整代码(可选)
目前项目中的完整代码有点长,但我认为下面显示的内容就足够了。
无论如何,如果您想检查所有内容,可以使用整个项目:flutter_firebase_auth_benchmark。
相关文件有:
firebase_auth.dart
:带有相关数据的provider
类。
login_screen.dart
:email_field
通过 Consumer
小部件提供 provider
数据。
password_reset_workflow.dart
:调用相关方法的按钮通过AnimatedSwitcher
放入LoginScreen
。
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,
);
);
最后,验证按钮在if
子句中使用formKey.currentState.validate()
异步触发await auth.sendPasswordResetWithEmail
。
【问题讨论】:
到目前为止,我最接近回答这个问题的是this SO answer。 【参考方案1】:notifyListeners() 显然与 catch 子句同时运行
notifyListeners()
在 finally
块内,finally
将始终被执行,无论是否有错误,这就是为什么总是调用 notifyListeners()
。
另外,使用Future.delayed
来同步事件是很糟糕的,你应该为它做另一个架构。
【讨论】:
我知道notifyListeners()
将始终被执行,但我希望它在错误处理之后执行,而不是在完成try
子句之后执行。而且我也知道使用Future.delayed
来同步事件非常糟糕,这可能是发布问题的全部原因。
“在错误处理之后而不是在try
之后”是什么意思?很抱歉,我无法理解您的英语
Fala em português que depois eu edito a resposta em inglês pra todo mundo entender。
从众多变体来看,代码执行的顺序似乎是:try
→ catch
与finally
并行。所以notifyListeners()
会在errorMsg
被更新时被调用。 Future.delayed
调用将使事情手动同步。但我不确定所有的顺序,这只是我在调试时能够猜到的。
Eu acho que você ta abusando um pouco dessa arquitetura... Você pode simplificar as coisas com FutureBuilder, StreamBuilder 等 e nem precisar de um ChangeNotifier以上是关于使用 Provider (Flutter) 包进行异步异常处理 (Firebase)的主要内容,如果未能解决你的问题,请参考以下文章
使用 geolocator 和 provider 以及 flutter_maps 获取位置