Issue
I need a little help with an issue I can’t seem to understand quite completely. I am pratcicing with AWS and I need to display a message for my Login screen after the user has logged in or to display an error message if the login has failed. The message is suppose to be in an AlertDialog or in a SnackBar, but I don’t understand how to call 2 functions on one button, one function that checks if the user is successfully logged and the other function being to display an AlertDialog or a SnackBar with the error message or success message from the function loginToCognito()
. In short, when a user presses Log In button, a message has to be returned as an AlertDialog or a SnackBar. Here is the code I’ve done so far:
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,
);
}
}
Thanks in advance for your time and help!
Solution
Simply, you want to show success/fail messages to users. But the solution for your purpose depends on how you interpret it.
For me, I’d code it like below,
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;
}
Now you can deal with the fail scenarios
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.
Answered By – blackkara
Answer Checked By – Katrina (FlutterFixes Volunteer)