Flutter Change password of firebase user is not working - firebase

I'm trying to implement change password for firebase user.
handleChangePassword(BuildContext parentContext) {
return showDialog(
context: parentContext,
builder: (_) {
return ChangePasswordPopUp(
currentEmail: widget.email,
auth: widget.auth,
newPassword: (val) async {
await widget.auth.changePassword(val);
},
);
});
}
The user gets reauthenticated in ChangePasswordPopUpand with ValueChanged newPassword I'm calling changePassword
Future<void> changePassword(String password) async {
FirebaseUser user = await _firebaseAuth.currentUser();
print(password);
user.updatePassword(password).then((_){
print("Succesfull changed password");
}).catchError((error){
print("Password can't be changed" + error.toString());
});
}
It prints the choosen new password and "Successful changes password" so everything should be fine but when I'm trying to logout and login again it is the old password which works and not the new one.
Any suggestions?

void _changePassword(String password) async{
//Create an instance of the current user.
FirebaseUser user = await FirebaseAuth.instance.currentUser();
//Pass in the password to updatePassword.
user.updatePassword(password).then((_){
print("Your password changed Succesfully ");
}).catchError((err){
print("You can't change the Password" + err.toString());
//This might happen, when the wrong password is in, the user isn't found, or if the user hasn't logged in recently.
});
}

Related

Avoid user Login with Firebase on Creation [duplicate]

This question already has an answer here:
Flutter - remove auto login after registration in Firebase
(1 answer)
Closed 1 year ago.
I have an app where users are supposed to be created only by Admin User's the problem is that when a new user is created in Firebase the app sign's in with the new user information, so the original logged user (Admin User), has to logged out, and log back in to create a new user.
This is my function to create a new User:
void createUser(
String email,
String password,
String nombre,
String dui,
DateTime fechaNacimiento,
String telefono,
String nombreContacto,
String telefonoContacto,
DateTime fechaIngreso,
String radio,
File foto,
String acceso,
) async {
try {
final auth = FirebaseAuth.instance;
UserCredential authResult = await auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
//var uploadUid = authResult.user?.uid;
final ref = FirebaseStorage.instance
.ref()
.child('user_images')
.child(authResult.user!.uid + '.jpg');
await ref.putFile(foto);
final url = await ref.getDownloadURL();
await FirebaseFirestore.instance
.collection('users')
.doc(authResult.user!.uid)
.set({
'nombre': nombre,
'dui': dui,
'fechaNacimiento': fechaNacimiento,
'telefono': telefono,
'nombreContacto': nombreContacto,
'telefonoContact': telefonoContacto,
'fechaIngreso': fechaIngreso,
'radio': radio,
'foto': url,
'acceso': acceso,
'uid': authResult.user!.uid,
'correo': email,
'contrasena': password,
});
} catch (err) {
print(err);
}
}
Any Ideas on what to do to avoid the log in on user creation of the newly created user.
Kind Regards
The original admin user does not have to be logged out to create a new user. Simply do this.
FirebaseApp secondaryApp = await Firebase.initializeApp(
name: 'SecondaryApp',
options: Firebase.app().options,
);
try {
UserCredential credential = await FirebaseAuth.instanceFor(app: secondaryApp)
.createUserWithEmailAndPassword(
email: 'email',
password: 'password',
);
if (credential.user == null) throw 'An error occured. Please try again.';
await credential.user.sendEmailVerification();
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
return _showError('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
return _showError('An account already exists for this email.');
}
} catch (e) {
return _showError('An error occured. Please try again.');
}
...
// after creating the account, delete the secondary app as below:
await secondaryApp.delete();
The above code will not logout the admin user, the admin user can still continue with normal operations after creating the account.

firebase is not creating the user (user.uid = null)

I am trying to implemente facebook signin in flutter, however, firebase does not create a 'uid'. Doesn't the firebase create a uid automatically?
it returns:
The getter 'uid' was called on null.
Receiver: null
Tried calling: uid
below is the sign in method:
Future<UserCredential> signInWithFacebook(BuildContext context) async {
final LoginResult result = await FacebookAuth.instance.login();
if(result.status == LoginStatus.success) {
final OAuthCredential credential = FacebookAuthProvider.credential(result.accessToken.token);
return await FirebaseAuth.instance.signInWithCredential(credential)
.then((user) async {
final graphResponse = await http.get(Uri.parse(
'https://graph.facebook.com/v2.12/me?
fields=name,picture,email&access_token=${result
.accessToken.token}'));
final Map profile = jsonDecode(graphResponse.body);
if (profile != null){
authService.createUser(name: name, email: email, dob: dob, sex: sex);
}
return user;
});
}
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => Profile()));
return null;
}
The sign in method returns a facebook alert dialog requesting the permission to share email, when press continue red screen with the error appears. why is the firestore not creating the user? Thanks! I am not familiar with the system and just learning.
create user method in authServices:
Future<bool> createUser(
{String name,
User user,
String email,
String password,
String phone,
String sex,
String dob}) async {
var res = await firebaseAuth.createUserWithEmailAndPassword(
email: '$email',
password: '$password',
);
if ((res.user != null)) {
await saveUserToFirestore(name, res.user, email, dob, phone, sex);
return true;
} else {
return false;
}
}
As far as I can understand your code you first login the user with Facebook and then again create a new user with createUserWithEmailAndPassword. If you use the same email for both the second one will fail and give you null.
To track the auth state for all providers use the onAuthStateChanged listener:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
More about it here.

Change password of firebase user in flutter

I want to change the password of a firebase account. To do that the user should enter the old password before. If it is correct then he is allowed to change pass. I used this code which is only for changing the pass and not comparing the old one.
void _changePassword(String password) async{
//Create an instance of the current user.
FirebaseUser user = await FirebaseAuth.instance.currentUser();
//Pass in the password to updatePassword.
user.updatePassword(password).then((_){
print("Successfully changed password");
}).catchError((error){
print("Password can't be changed" + error.toString());
//This might happen, when the wrong password is in, the user isn't found, or if the user hasn't logged in recently.
});
}
The idea is to verify old password by resigning in user using firebaseAuth, you can get user email by passing user.email to string, and let user input old password. If sign in proccess failed, password change shouldn't happen.
void _changePassword(String password) async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
String email = user.email;
//Create field for user to input old password
//pass the password here
String password = "password";
String newPassword = "password";
try {
UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
user.updatePassword(newPassword).then((_){
print("Successfully changed password");
}).catchError((error){
print("Password can't be changed" + error.toString());
//This might happen, when the wrong password is in, the user isn't found, or if the user hasn't logged in recently.
});
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
}
it will not allow you to verify its previous or old password . it will directly send email for forgot and there you need to add your new password . and and you have to back again to application and your password will be updated as you wil try to login .
If the user hasn't signed in recently, Firebase will automatically require them to reauthenticate before they can change their password (or perform other sensitive operations). So you typically should only require the user to reauthenticate when Firebase tells you to.
When that happens, follow the steps in the documentation on reauthenticating a user.

Firebase + Flutter: can't lock access to unverified email accounts

I'd like to block out people who didn't verify their email so i figured out this code for sign up:
// sign up
Future signUp(String email, String password) async {
try {
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
} catch (e) {
print('An error has occured by creating a new user');
print(
e.toString(),
);
}
try {
final FirebaseUser _user = await _auth.currentUser();
await _user.sendEmailVerification();
} catch (error) {
print("An error occured while trying to send email verification");
print(error.toString());
}
try {
await _auth.signOut();
} catch (err) {
print(err);
}
}
and this for sign in:
//Sign In with Email and Pass
Future signInWithEmailAndPassword(String email, String password) async {
FirebaseUser _user = await FirebaseAuth.instance.currentUser();
if (_user != null && _user.isEmailVerified == true) {
try {
await _auth.signInWithEmailAndPassword(
email: email, password: password);
return _user;
} catch (e) {
return null;
}
} else {
return null;
}
}
_auth is just an instance of FirebaseAuth.
The problem is that i can login even if i didnt verify the email.
Firebase Auth doesn't stop accounts from signing in if the user hasn't verified their email address yet. You can check that property _user.isEmailVerified to find out the state of that validation after the user signs in, and you can determine from there what the user should see.
isEmailVerified can be a little bit of trouble to get working correctly.
Make sure you are calling
await FirebaseAuth.instance.currentUser()..reload();
before your are calling isEmailVerified also in my own experience and I don't know if this is just something I was doing wrong but this did not work from my Auth class this did not start working until I put the code directly in initState() of my widget that checks whether the user is verified. Like I said that part might have been something I did wrong. Like stated this will not listen for change you must check yourself either periodically or at a point that you know email is verified.
Future(() async {
_timer = Timer.periodic(Duration(seconds: 10), (timer) async {
await FirebaseAuth.instance.currentUser()
..reload();
var user = await FirebaseAuth.instance.currentUser();
if (user.isEmailVerified) {
timer.cancel();
Navigator.of(context).popAndPushNamed(HearingsScreen.routeName);
}
});
});
So it checks every 10 seconds to see if the user has verified their email not the most elegant solution. The page I have this on just displays a message 'Please verify your email' so its not like this is interrupting other code. If your app is performing other tasks this might not be an option for you. If you want to play around with isEmailVerified go ahead but i spent a week of headaches until i settled on this.

I need to add email/password authentication with flutter and firebase

I have a Google authentication working just fine, and I need to create another signUp method (with email/and password), so what are the best approaches for implementing this signUp method?
I tried to create a user and it worked. But then I can't navigate to my other pages!
I couldn't find any good blog posts or documentation. Note that when the user signs up I also need to add them in firebase Database.
Try something like this:
emailPasswordLogin(BuildContext context, String email, String password)async{
try {
AuthResult authResult = await _auth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = authResult.user;
} catch (ex) {
print("Code: " + ex.code);
switch (ex.code) {
case 'ERROR_USER_NOT_FOUND':
{
await createUser(email, password, context);
}
case 'ERROR_WRONG_PASSWORD':
print("wrong password);
break;
case 'ERROR_INVALID_EMAIL':
print("invalid email")
break;
case 'ERROR_OPERATION_NOT_ALLOWED':
print("Login Method not defined")
break;
case 'ERROR_WEAK_PASSWORD':
print("weak password")
break;
default:
print('Case ${ex.message} is not yet implemented');
}
return;
}
storeData(user, context);
}
storeData(FirebaseUser user, BuildContext context) async {
_database = new FirebaseDatabase();
await _database
.reference()
.child('user')
.push().set(<dynamic, dynamic> async{
"email": user.email,
}).then((_) {
print("Transaction commited");
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => NextPage());
});
}

Resources