1. Проблема
Я использую try-catch-finally
1 dynamici c для обработки исключений для Firebase в моем простом пакете аутентификации для моего приложения. В нем, когда я получаю сообщение об ошибке от службы аутентификации Firebase, я обновляю labelText
в (настраиваемом) TextFormField
, чтобы показать пользователю, что произошла ошибка.
Однако, notifyListeners()
явно запускается одновременно с предложением catch
, в результате чего перестройки не происходят синхронно с обработкой исключений.
В настоящее время я использую ChangeNotifierProvider
для всего, но я должен перейти на FutureProvider
Dynami c. Если да, то как лучше это сделать?
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 My Custom TextFormField
Виджет
Примерно так находится в приложении:
return Consumer<Auth>(
builder: (context, auth, _) {
return AuthTextFormField(
...,
errorMsgFromServer: auth.errorMsg,
);
}
);
Наконец, кнопка проверки использует formKey.currentState.validate()
в предложении if
для асинхронного запуска await auth.sendPasswordResetWithEmail
.