我需要一点帮助,有一个问题我似乎不能完全理解。我正在使用AWS进行练习,我需要在用户登录后为我的登录屏幕显示一条消息,或者在登录失败时显示一条错误消息。该消息应该是在AlertDialog或SnackBar中,但我不明白如何在一个按钮上调用2个函数,一个函数检查用户是否成功登录,另一个函数显示AlertDialog或SnackBar与错误消息或成功消息来自函数loginToCognito()
。简而言之,当用户按下Log In按钮时,必须以AlertDialog或SnackBar的形式返回消息。下面是我到目前为止完成的代码:
import 'package:flutter/material.dart';
import 'package:flutter_client/modules/module2/components/login_form_buttons.dart';
import 'package:flutter_client/modules/module2/constants/styles.dart';
import 'package:amazon_cognito_identity_dart_2/cognito.dart';
class User {
String email;
String name;
String password;
bool confirmed = false;
bool hasAccess = false;
User({this.email, this.name});
factory User.fromUserAttributes(List<CognitoUserAttribute> attributes) {
final user = User();
attributes.forEach((attribute) {
if (attribute.getName() == 'email') {
user.email = attribute.getValue();
} else if (attribute.getName() == 'name') {
user.name = attribute.getValue();
}
});
return user;
}
}
class UserService {
CognitoUserPool _userPool;
CognitoUser _cognitoUser;
CognitoUserSession _session;
UserService(this._userPool);
CognitoCredentials credentials;
Future<User> login(String email, String password) async {
print('login initiated');
_cognitoUser = CognitoUser(email, _userPool, storage: _userPool.storage);
final authDetails = AuthenticationDetails(
username: email,
password: password,
);
bool isConfirmed;
try {
_session = await _cognitoUser.authenticateUser(authDetails);
isConfirmed = true;
print('logged in successfully');
} on CognitoClientException catch (e) {
if (e.code == 'UserNotConfirmedException') {
isConfirmed = false;
} else {
rethrow;
}
}
if (!_session.isValid()) {
return null;
}
final attributes = await _cognitoUser.getUserAttributes();
final user = User.fromUserAttributes(attributes);
user.confirmed = isConfirmed;
user.hasAccess = true;
print(user);
return user;
}
}
class LoginScreen extends StatefulWidget {
static const String id = 'login_screen';
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
bool showSpinner = false;
String email;
String password;
final _userService = UserService(userPool);
User _user = User();
void loginToCognito() async {
print('login button pressed, loggin with email, password: ' +
email +
', ' +
password);
String message;
try {
_user = await _userService.login(email, password);
message = 'User successfully logged in!';
if (!_user.confirmed) {
message = 'Please confirm user account';
}
} on CognitoClientException catch (e) {
if (e.code == 'InvalidParameterException' ||
e.code == 'NotAuthorizedException' ||
e.code == 'UserNotFoundException' ||
e.code == 'ResourceNotFoundException') {
message = e.message;
} else {
message = 'An unknown client error occurred';
}
} catch (e) {
message = 'An unknown error occurred';
print('Unknown error while logging in:');
print(e);
}
print(message);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
child: Hero(
tag: 'login',
child: Container(
height: 200.0,
child: Image.asset('lib/modules/module2/images/login.png'),
),
),
),
SizedBox(
height: 48.0,
),
TextField(
keyboardType: TextInputType.emailAddress,
textAlign: TextAlign.center,
onChanged: (value) {
//Do something with the user input.
email = value;
},
decoration:
kTextFieldDecoration.copyWith(hintText: 'Enter your email'),
),
SizedBox(
height: 8.0,
),
TextField(
obscureText: true,
textAlign: TextAlign.center,
onChanged: (value) {
//Do something with the user input.
password = value;
},
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your password'),
),
SizedBox(
height: 24.0,
),
LoginFormButtons(
buttonColour: Colors.grey,
buttonText: 'Log In',
buttonTextColour: Colors.white,
onButtonPress: () {
loginToCognito();
},
),
],
),
),
);
}
}
LoginFormButtons
import 'package:flutter/material.dart';
class LoginFormButtons extends StatelessWidget {
LoginFormButtons ({
this.buttonText,
this.buttonTextColour,
this.buttonColour,
@required this.onButtonPress,
});
final String buttonText;
final Function onButtonPress;
final Color buttonTextColour;
final Color buttonColour;
@override
Widget build(BuildContext context) {
return FlatButton(
minWidth: 300.0,
height: 50.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: buttonColour,
textColor: buttonTextColour,
child: Text(
buttonText,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w400,
),
),
onPressed: onButtonPress,
);
}
}
提前感谢您的时间和帮助!
简单地说,您希望向用户显示成功/失败消息。但你的目的的解决方案取决于你如何解释它。
对于我来说,我会像下面这样编码,
try {
// Unless we jump to catch scopes, everything is okay
// So, returning the function in try scope will decrease complexity
_user = await _userService.login(email, password);
message = 'User successfully logged in!';
if (!_user.confirmed) {
message = 'Please confirm user account';
}
// <====== Show your success dialog/toast etc. then return
return;
}
现在您可以处理失败场景
on CognitoClientException catch (e) {
if (e.code == 'InvalidParameterException' ||
e.code == 'NotAuthorizedException' ||
e.code == 'UserNotFoundException' ||
e.code == 'ResourceNotFoundException') {
message = e.message;
} else {
message = 'An unknown client error occurred';
}
} catch (e) {
message = 'An unknown error occurred';
print('Unknown error while logging in:');
print(e);
}
// <====== Show your fail dialog/toast etc.