When a user enters their information in an overlay, presses submit, 4 things should happen.
- User's account is registered in firestore
- User has a document created with their info
- the overlay is closed
- nav() page is called
On the first click, [1] happens and then stops at the collection reference. On the second click, [1] fails, but [2-4] successfully go through. I think it has to do with when the user info not coming back from the registry fast enough but the prints are coming back correctly so I'm not sure.
onPressed function in overlay
onPressed: () async{
await register(_email, _password);
await signUp(_email, firstName, lastName, userName);
hideNewUserOverlay();
var navTab = 2;
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const Nav(),
settings: RouteSettings(arguments: navTab)
));
}
Register and Sign Up
Future<void> register(String email, String password) async {
try {
// ignore: unused_local_variable
await auth.createUserWithEmailAndPassword(
email: email,
password: password); // <-- user account is created on first press
} catch (e) {
debugPrint('>> register: create new user error');
}
user = auth.currentUser!;
debugPrint(' register: current user got');
String userID = user.uid;
debugPrint(' register: user.id = $userID');
}
Future<void> signUp(
String email, String firstName, String lastName, String userName) async {
user = auth.currentUser!;
debugPrint('>> signUp: current user got');
String userID = user.uid;
debugPrint(' signUp: user.id = $userID'); // all debugs print out correctly
try {
debugPrint(' signUp: document creation code Start');
await collectionReference.doc(userID).set({ // first click stops here, takes 2 clicks to finish
'profileImageUrl': 'https://firebasestorage.googleapis.com/v0/b/commentaries-d82cd.appspot.com/o/defaultProfileImage.png?alt=media&token=07e4d649-3da7-4f9f-8cf9-062ac9cc9507',
'userID': userID,
'accountCreated': DateTime.now(),
'email': email,
'userName': userName,
'firstName': firstName,
'lastName': lastName,
});
debugPrint(' signUp: User Document Created');
} catch (e) {
debugPrint(' signUp: create new user error');
}
}
CodePudding user response:
I think it doesn't work all at once because you are making asynchronous calls but your onPressed function is not async
Try this:
onPressed: () async{
await register(_email, _password);
await signUp(_email, firstName, lastName, userName);
hideNewUserOverlay();
var navTab = 2;
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const Nav(),
settings: RouteSettings(arguments: navTab)
));
}
CodePudding user response:
You can add callback to your functions, so you know they are done. See:
Future<void> register(String email, String password, VoidCallback callback) async {
try {
// ignore: unused_local_variable
await auth.createUserWithEmailAndPassword(
email: email,
password: password); // <-- user account is created on first press
} catch (e) {
debugPrint('>> register: create new user error');
}
user = auth.currentUser!;
debugPrint(' register: current user got');
String userID = user.uid;
debugPrint('register: user.id = $userID');
callback(); //here you will send the flag informing the job is done.
}
Now let´s do the same with the other function.
Future<void> signUp(
String email, String firstName, String lastName, String userName, VoidCallback callback) async {
user = auth.currentUser!;
debugPrint('>> signUp: current user got');
String userID = user.uid;
debugPrint(' signUp: user.id = $userID'); // all debugs print out correctly
try {
debugPrint(' signUp: document creation code Start');
await collectionReference.doc(userID).set({ // first click stops here, takes 2 clicks to finish
'profileImageUrl': 'https://firebasestorage.googleapis.com/v0/b/commentaries-d82cd.appspot.com/o/defaultProfileImage.png?alt=media&token=07e4d649-3da7-4f9f-8cf9-062ac9cc9507',
'userID': userID,
'accountCreated': DateTime.now(),
'email': email,
'userName': userName,
'firstName': firstName,
'lastName': lastName,
});
debugPrint(' signUp: User Document Created');
callback();
} catch (e) {
debugPrint(' signUp: create new user error');
}
}
now you can make this with steps:
onPressed: () async{
await register(_email, _password, (){
await signUp(_email, firstName, lastName, userName, (){
hideNewUserOverlay();
var navTab = 2;
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const Nav(),
settings: RouteSettings(arguments: navTab)
));
});
});
}
Explaination: What I did was to place the next step inside the callback. So, you know everything will continue only when you really want it to. next things to do to make your code better:
- Named paramters to help code reading.
- Create functions to callbacks, making the code more readable too and maintenable.
- remove the awaits no more needed.
- Create a Loading while the process go, as this can take long.
- Create a block to not allow multiples clicks in this button.
- Create callbacks to handle failures.
