如何解决showDialog() - 尝试根据从 Firebase Authentication API 调用检索到的错误消息触发对话框模式
我正在尝试为我的应用建立错误处理。
后端是 Firebase。
预期功能:
我相信在 Auth 类中建立的 HttpException 逻辑不会通过提供者传递,因此方法 on HttpException catch (error)
调用的是 HttpException 而不是在 Auth 提供者中建立的逻辑。
I/Flutter (29822): {error: {code: 400,message: EMAIL_NOT_FOUND,errors: [{message: EMAIL_NOT_FOUND,domain: global,reason: invalid}]}}
我正在尝试定位错误响应中的消息
final responseData = json.decode(response.body);
if (responseData['error'] != null) {
//if the API call retrieves an error
throw HttpException(
//throw custom error handling method
message: responseData['error']['message'],//display the error message returned in the API call (the value assigned to the message within the error array)
);
}
然后通过Provider传递。
持有 API 调用的提供者:
class Auth with ChangeNotifier {
String _token;
DateTime _tokenExpirationDate;
String _userID;
final String apiKey = #; //redacted
//AUTHENTICATION method - extracted to reduce reuse of code
Future<void> _authenticate(
{String email,String password,String urlSegment}) async {
final url = Uri.parse(
'https://identitytoolkit.googleapis.com/v1/accounts:$urlSegment?key=$apiKey');
//.parse method allows the use of the full url
try {
final response = await http.post(
url,body: json.encode({
'email': email,'password': password,'returnSecuretoken': true,}),);
final responseData = json.decode(response.body);
if (responseData['error'] != null) {
//if the API call retrieves an error
throw HttpException(
//throw custom error handling method
message: responseData['error']['message'],//display the error message returned in the API call (the value assigned to the message within the error array)
);
}
print(response.statusCode);
} catch (error) {
throw error;
}
}
//AUTHENTICATION CREATE API call - Register user
Future<void> signup(String email,String password) async {
_authenticate(
email: email,password: password,urlSegment: 'signUp',);
}
//AUTHENTICATION READ API call - user sign in
Future<void> signin(String email,urlSegment: 'signInWithPassword',);
}
}
标准化的错误处理类:
class HttpException implements Exception {
HttpException({this.message});
final String message;
@override
String toString() {
return message;
}
}
显示 UI 和交互逻辑的身份验证卡:
//VOID function to display a dialog modal. We will use this to display a dialog modal and populate the message with whatever error message the API call returns
void _errorDialog({String message}) {
showDialog(
//in the case that an error occurs,by us putting the return in front of showDialog,showDialog will fulfill that Future in case of the error. If there is no error the .then will fulfill the expected Future value
context: context,builder: (ctx) => AlertDialog(
title: Text('An error occurred'),content: Text(message),//we will change the value of message to display according to what the API call returns
actions: [
TextButton(
child: Text('Okay'),onpressed: () {
Navigator.of(ctx).pop();
},),],);
}
//SUBMIT button logic
Future<void> _submit() async {
if (!_formKey.currentState.validate()) {
// Invalid!
return;
}
//Invalid response from user
_formKey.currentState.save();
setState(() {
_isLoading = true;
});
//ATTEMPT TO MAKE API CALLS BASED ON ENUM STATE OF disPLAY
try {
if (_authMode == AuthMode.Login) {
//USER LOGIN
//call the sign in (read) API
await Provider.of<Auth>(context,listen: false).signin(
_authData['email'],_authData['password'],);
} else {
//REGISTER USER
//call the register (create) API
await Provider.of<Auth>(context,listen: false).signup(
_authData['email'],);
}
} on HttpException catch (error) {
//we are conducting a filter on the type of errors we want to handle within this block.
//here we are calling on the HttpException
var httpErrorMessage = 'Could not login or sign up.';
//all of the following error messages were retrieved from the Firebase Auth API documentation
if (error.toString().contains('EMAIL_EXISTS')) {
//if the API call retrieves a value of 'EMAIL_EXISTS' in the error message
httpErrorMessage = 'This email is alreary in use';
//display the above error message
} else if (error.toString().contains('INVALID_EMAIL')) {
//if the API call retrieves a value of 'INVALID_EMAIL' in the error message
httpErrorMessage = 'This is not a valid email.';
//display the above error message
} else if (error.toString().contains('INVALID_EMAIL')) {
//if the API call retrieves a value of 'INVALID_EMAIL' in the error message
httpErrorMessage = 'This is not a valid email.';
//display the above error message
} else if (error.toString().contains('EMAIL_NOT_FOUND')) {
//if the API call retrieves a value of 'EMAIL_NOT_FOUND' in the error message
httpErrorMessage = 'Could not find a user with that email.';
//display the above error message
} else if (error.toString().contains('INVALID_PASSWORD')) {
//if the API call retrieves a value of 'INVALID_PASSWORD' in the error message
httpErrorMessage = 'Invalid password.';
//display the above error message
}
_errorDialog(message: httpErrorMessage);
//call the error dialog method
//display in the message whatever defined message to display according to the API error response
} catch (error) {
//calling on the error that was established in the Auth class catch(error) {throw error} method in the addProduct function
const errorMessage =
'Experiencing network difficulties. Please try again';
_errorDialog(message: errorMessage);
//call the error dialog method
//display in the message whatever defined message to display according to the API error response
}
setState(() {
_isLoading = false;
});
}
解决方法
我没有在 signIn、signUp 未来方法中返回任何内容。我需要返回 _authenticate 方法:
//AUTHENTICATION CREATE API call - Register user
Future<void> signup(String email,String password) async {
return _authenticate(
email: email,password: password,urlSegment: 'signUp',);
}
//AUTHENTICATION READ API call - user sign in
Future<void> signin(String email,urlSegment: 'signInWithPassword',);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。