How to make Flutter sign up with more fields? - firebase

My sign up page has the following fields Names, password, confirm password and email but it seems flutter firebase only works for email and password.
How do I make more fields work in the below code:
createUser()async{
if (checkFields()){
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: _email, password: _password)
.then((user){
print('signed in as ${user.uid}');
Navigator.push(context, MaterialPageRoute(builder: (context)=> (Usertype())));
}).catchError((e){
print(e);
});
}
}

Unfortunately, you cannot make Firebase accept Names on sign up event.
But you can update user information after sign up.
Use updateProfile method after authentication is successfully complete.
You can check this as Android example, and here as the method from the Flutter package.
In your case,
createUser()async{
if (checkFields()){
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: _email, password: _password)
.then((user){
print('signed in as ${user.uid}');
var userUpdateInfo = new UserUpdateInfo(); //create user update object
userUpdateInfo.displayName = name; //set user display name to your variable.
await firebaseAuth.updateProfile(userUpdateInfo); //update the info
await user.reload(); //reload the user data
Navigator.push(context, MaterialPageRoute(builder: (context)=> (Usertype())));
}).catchError((e){
print(e);
});
}
}

Related

Flutter firebase authentication login success no matter if the user is in the database

If I try to fill TextFormFields responsible for email and password and submit, the login procedure gonna be success always.. no matter if user is in firebase authentication field. I've done login and register pages before with firebase working perfectly. Only diffrence was using pushNamed instead pushReplace. Should it do difference?
That's form inkwell onTap :
onTap: () {
final formState = _formkey.currentState;
if (formState.validate()) {
formState.save();
signIn(_email, _password).whenComplete(
() => Navigator.of(context)
.pushReplacement(
MaterialPageRoute(
builder: (context) =>
HomePage(),
)));
}
}
and authentication:
FirebaseAuth _auth = FirebaseAuth.instance;
Future<void> signIn(String _email, String _password) async {
try {
UserCredential user = await _auth.signInWithEmailAndPassword(
email: _email, password: _password);
} on FirebaseAuthException catch (e) {
print('error');
}
}
Email/password sign-in method is turn on.
How to fix this problem and allow to log in only users that exist in firebase?

how to verify email and password flutter firebase

i'm new with flutter and i want to implement a log in screen on my application.
for that i use flutter and firebase.
the problem is that when anything in the email and password field the application access to the home.
so i need to verify the email before get the access.
here is the code
thanks guys for help me,
onPressed: () {
if (_formKey.currentState.validate()) {
Future<String> check = logIn();
if (check != null) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
HomePage()));
}
}
Firebase offers a function for checking if users are verified which I used in the code below.
Future<bool> login(
String email, String password) async {
final user = (await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password))
.user;
if (user.isEmailVerified) {
return true;
}
return false;
}
However, to use this function, you have first send an email verification to your users somewhere in the function you call when your users create an account. The function below will create the user and send a verification email and then return a FirebaseUser when done.
Future<FirebaseUser> register() async {
await _auth
.createUserWithEmailAndPassword(email: email.trim(), password: password)
.then(
(result) async {
//send verifcation email
result.user.sendEmailVerification();
return result.user;
},
);
return null;
}

Firebase error when trying to create an account

I wrote a function for creating accounts in Firebase two months ago and it worked, now when I try to create an account it gives me the next error message:
I/BiChannelGoogleApi(19700): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq#94e857b
The function that I created for doing that stuff is the next one:
Future<void> register() async {
final formState = _formKey.currentState;
if (formState.validate()) {
formState.save();
print('$_email si $_password');
try {
FirebaseUser user = (await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: _email.trim(), password: _password, ))
.user;
user.sendEmailVerification();
presentError("Now you own an account", context);
await Future.delayed(Duration(seconds: 1));
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => LoginPageState(title: 'LoginPage')));
} catch (e) {
print(e);}
Maybe you don't have updated your FirebaseAuth Rules and the unsafe period is over.
See https://firebase.google.com/docs/rules/rules-and-auth

How to detect an async operation is successful or not in Flutter

In my app, after authentication, user can move to the next screen.
signUpWithEmail().then((user) {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return HomePage();
}));
}).catchError((error) {
print("THE ERROR : $error");
});
Now signUpWithEmail may fail for various reasons like : invalid e-mail, internet connectivity failure and so on. How can I detect those errors and prevent navigation? Here is signUpWithEmail() method:
Future<FirebaseUser> signUpWithEmail() async {
String email = emailControlller.text;
String password = passwordControlller.text;
FirebaseUser user = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: emailControlller.text,
password: passwordControlller.text,
)
.then((user) {
// set balance to 0
Firestore.instance
.collection("users")
.document(user.uid)
.setData({"cash": 0});
}).catchError((e) => print("error : $e"));
return user;
}
You is returning to signUpWithEmail() of anyway, you don't throw the error, so it never will enter on
.catchError((error) {
print("THE ERROR : $error");
})
To fix it you must throw the error on your signUpWithEmail(). Try something like it.
Future<FirebaseUser> signUpWithEmail() async {
String email = emailControlller.text;
String password = passwordControlller.text;
FirebaseUser user = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: emailControlller.text,
password: passwordControlller.text,
)
.then((user) {
// set balance to 0
Firestore.instance
.collection("users")
.document(user.uid)
.setData({"cash": 0});
}).catchError((e) => {
print("error : $e")
throw("Your error") // It return to catch
});
return user;
}
Let me know if you can make it.
Use FutureBuilder widget and wrap the logic in the builder method

Flutter + Firebase updateDisplayName when creating account with Email and Password

I'm new to Flutter and really, really new to firebase.
I'm trying to create a user via the createUserWithEmailAndPasswordMethod.
I've successfully created on, but I'm trying to improve it by allowing the user to enter the desired username and setting said username to the displayName attribute.
My code is as follows:
_createUser() async {
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = _usernameController.text;
FirebaseUser user = await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
.then((user) {
user.updateProfile(updateInfo);
});
print('USERNAME IS: ${user.displayName}');
}
The problem is when I run the app it always throws this exception:
NoSuchMethodError: The getter 'displayName' was called on null.
Every time I debug the user variable keeps showing as null as well, even though the user is created and I can print the email and password!
I guess the problem is that Firebase user is null, but even if I move the print('USERNAME IS: ${user.displayName}'); to right after updateProfile the same happens.
Hope you guys can help!
Thanks.
You should not use await and then together. await is a substitute for then method.
_createUser() async {
await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
FirebaseUser user = await _auth.currentUser();
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = _usernameController.text;
user.updateProfile(updateInfo);
print('USERNAME IS: ${user.displayName}');
}
So, what worked for me was this: I had to call the reload() method to get the new user information after the updateProfile(). After some changes the method looks like this:
_createUser() async {
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = _usernameController.text;
await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
.then((user) async {
await user.updateProfile(updateInfo);
await user.reload();
FirebaseUser updatedUser = await _auth.currentUser();
print('USERNAME IS: ${updatedUser.displayName}');
Navigator.of(context).push(
MaterialPageRoute<Map>(
builder: (BuildContext context) {
return Posts(_googleSignIn, updatedUser);
},
),
);
}).catchError((error) {
print('Something Went Wrong: ${error.toString()}');
});
}
If someone is still searching, this is the working solution in 2021.
UserCredential userCred = await _auth.createUserWithEmailAndPassword(email, password);
await userCred.user.updateProfile(displayName: "Your Name");

Resources