So I am trying to implement a change password feature. I am able to to do it using updatePassword (newPassword) method. I would like to do some verification before this.So for example when the user wants to change his password, he presses a button and then:
User enters current password
User enters new password
User enters new password again.
How do I verify that the current password the user inputted is correct? There does not seem to be a method that gets me the current password of the user to compare it with.
What you are looking for is "Re-authenticate a user" which is discussed in Firebase's authentication documention. The idea is that you must have the user re-enter their old information into the user.reauthenticate method and firebase will verify the information and you continue operations in onComplete if successful, or firebase sends you an exception. You would use updatePassword in onComplete like below. Your UI would look like its one transaction but really its reAuthenticate -> updatePassword. You additionally may be able to assume the user username/email based on how you store user information.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String newPassword = "SOME-SECURE-PASSWORD";
// Get auth credentials from the user for re-authentication. The
//example below shows
// email and password credentials but there are multiple possible
//providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// The email and password should be extracted from an EditText
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
user.updatePassword(newPassword)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User password updated.");
}
}
});
}
});
Related
I'm trying to update the user's email, but firebase requires a recent login for this, so I tried to use the method that was in the firebase documentation, but the problem is how I can pass the password user? I do not keep the password in db, and I can not get it from the firebase, so I do not know how I can pass the password.
The solution I thought is to ask the user to enter the password, so I tried to use a field to enter the password but it still does not work, so how can I pass the password to the firebase and reauthenticate the user to change the data?
You need to re-authenticate a user, referring to documentation.
For instance you have a field where the user types his password, let's say it`s an EditText etPassword, and you have user email in SharedPreferences
So the code to re-authenticate will look like this:
AuthCredential credential = EmailAuthProvider
.getCredential(SharedPreferences.getmail(),etPassword.getText().toString());
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
if(task.isSuccessful()){
updateUserEmail();
} else {
// Password is incorrect
}
}
});
where updateUserEmail() is
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.updateEmail("user#example.com")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User email address updated.");
}
}
});
I'm using the following steps to sign-up a new Firebase user. Is there a way for me to set a username parameter so in the future the user can login using a username & password ?
Also, is there a way to sign up only using a username & password ,ie, I would not like to have an option of e-mail ID.
I've gone through the following solution, but it doesn't seem efficient. I suppose there is a better way of doing so.
Firebase login and signup with username
private FirebaseAuth auth;
//Get Firebase auth instance
auth = FirebaseAuth.getInstance();
//create user
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignupActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toast.makeText(SignupActivity.this, "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show();
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Toast.makeText(SignupActivity.this, "Authentication failed." + task.getException(),
Toast.LENGTH_SHORT).show();
} else {
startActivity(new Intent(SignupActivity.this, MainActivity.class));
finish();
}
}
});
You can add any domain behind the username
register your user with < username > #summersApp.com.
Note that this will make it impossible to for the user to reset their password if they forget it, since Firebase uses the email address to send the password reset email.
To answer OP's question in comments above,
To save extra information to a user, link a reference in the database to their UID as shown here
Example:
/users
/uid1
no.of.posts: 3,
no.of.friends: 4
/uid2
no.of.posts: 5,
no.of.friends: 6
/uid3
no.of.posts: 7,
no.of.friends: 8
I want to implement change password functionality for my application.
I included com.google.firebase:firebase-auth:9.0.2 in my build.gradle file and so far everything has been working fine until I tried to implement change password functionality.
I found that the FirebaseUser object has a updatePassword method that takes a new password as the parameter. I could use this method and implement validation myself. However, I need the user's current password for comparing with the inputted one and I can't find a way to get that password.
I also found another method on the Firebase object that takes the old password, new password, and a handler. The problem is that I need to also include com.firebase:firebase-client-android:2.5.2+ to access this class and when I am trying this method I'm getting to following error:
Projects created at console.firebase.google.com must use the new Firebase Authentication SDKs available from firebase.google.com/docs/auth/
Feel like I'm missing something here. What's the recommended approach for implementing this? And when to use what dependency?
I found a handy example of this in the Firebase docs:
Some security-sensitive actions—such as deleting an account, setting a
primary email address, and changing a password—require that the user
has recently signed in. If you perform one of these actions, and the
user signed in too long ago, the action fails and throws
FirebaseAuthRecentLoginRequiredException. When this happens,
re-authenticate the user by getting new sign-in credentials from the
user and passing the credentials to reauthenticate. For example:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Password updated");
} else {
Log.d(TAG, "Error password not updated")
}
}
});
} else {
Log.d(TAG, "Error auth failed")
}
}
});
Changing password in firebase is bit tricky. it's not like what we usually do for changing password in server side scripting and database. to implement change password functionality in your app, first you need to get the user's email from FirebaseAuth or prompt user to input email and after that prompt the user to input old password because you can't retrieve user's password as Frank van Puffelen said. After that you need to reauthenticate that. Once reauthentication is done, if successful, you can use updatePassword(). I have added a sample below that i used for my own app. Hope, it will help you.
private FirebaseUser user;
user = FirebaseAuth.getInstance().getCurrentUser();
final String email = user.getEmail();
AuthCredential credential = EmailAuthProvider.getCredential(email,oldpass);
user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(!task.isSuccessful()){
Snackbar snackbar_fail = Snackbar
.make(coordinatorLayout, "Something went wrong. Please try again later", Snackbar.LENGTH_LONG);
snackbar_fail.show();
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Password Successfully Modified", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Authentication Failed", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}
}
There is no way to retrieve the current password of a user from Firebase Authentication.
One way to allow your users to change their password is to show a dialog where they enter their current password and the new password they'd like. You then sign in (or re-authenticate) the user with the current passwordand call updatePassword() to update it.
I googled something about resetting Firebase passwords and got to this page. It was helpful but didn't get me all the way to the finish line: I still had to Google around for five or ten minutes. So I'm back to improve the answer for VueJS users.
I see lots of code here using "FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();" in the top line. That's a piece of the puzzle mentioned in the most popular two answers.
But I couldn't get that to work in my project, which is written in VueJS. So I had to go exploring.
What I found was another page of the Firebase documentation. It's the same page people are getting the quoted code from (I think), but with the documentation written for Web instead of Android/Java.
So check out the first link if you're here using VueJS. I think it'll be helpful. "Get the currently signed-in user" might contain the appropriate code for your project. The code I found there says:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
That page I linked up above ("another page") brought me eventually to the "Set a user's password" part of the Web docs. Posters here correctly state that the user must have been authenticated recently to initiate a password update. Try this link for more on re-authenticating users.
"Set a user's password":
// You can set a user's password with the updatePassword method. For example:
var user = firebase.auth().currentUser;
var newPassword = getASecureRandomPassword();
user.updatePassword(newPassword).then(function() {
// Update successful.
}).catch(function(error) {
// An error happened.
});
"Re-authenticate a user"
var user = firebase.auth().currentUser;
var credential;
// Prompt the user to re-provide their sign-in credentials
user.reauthenticateWithCredential(credential).then(function() {
// User re-authenticated.
}).catch(function(error) {
// An error happened.
});
Query revolves around users forgetting their passwords or wishing to reset their passwords via an email letter. Which can be attained by Auth.sendPasswordResetEmail("email#gmail.com");
begin by initializing
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String DummyEmail = "Dummy#gmail.com"
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
}
}
};
Somewhere else when a user requests to update or reset their passwords simply access the mAuth,
private void PassResetViaEmail(){
if(mAuth != null) {
Log.w(" if Email authenticated", "Recovery Email has been sent to " + DummyEmail);
mAuth.sendPasswordResetEmail(DummyEmail);
} else {
Log.w(" error ", " bad entry ");
}
}
Now, needless to burden yourself querying around your database to find whether the Email exits or not, Firebase mAuth will handle that for you.
Is the Email authenticated? Is it active in your Authentication list? Then send a password-reset Email.
The content will look something like this
the reset link will prompt the following dialog on a new web page
Extra
if you're bit nerved by the reset-template "devised" by Firebase. You can easily access and customize your own letter from the Firebase Console.
Authentication > Email templates > Password reset
A simple approach to handle changing a password is to send a password reset email to the user.
FirebaseAuth.getInstance().sendPasswordResetEmail("user#example.org")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(Activity.this, "Password Reset Email Sent!"), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(Activity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
This is a kotlin solution to the problem I am putting the method here Hope it helps
// The method takes current users email (currentUserEmail), current users old password (oldUserPassword), new users password (newUserPassword) as parameter and change the user password to newUserPassword
private fun fireBasePasswordChange(
currentUserEmail: String,
oldUserPassword: String,
newUserPassword: String
) {
// To re authenticate the user credentials getting current sign in credentials
val credential: AuthCredential =
EmailAuthProvider.getCredential(currentUserEmail, oldUserPassword)
// creating current users instance
val user: FirebaseUser? = FirebaseAuth.getInstance().currentUser
// creating after successfully re authenticating update password will be called else it will provide a toast about the error ( makeToast is a user defined function here for providing a toast to the user)
user?.reauthenticate(credential)?.addOnCompleteListener { task ->
when {
task.isSuccessful -> {
user.updatePassword(newUserPassword).addOnCompleteListener {
if (it.isSuccessful) {
makeToast("Password updated")
// This part is optional
// it is signing out the user from the current status once changing password is successful
// it is changing the activity and going to the sign in page while clearing the backstack so the user cant come to the current state by back pressing
FirebaseAuth.getInstance().signOut()
val i = Intent(activity, SignInActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i)
(activity as Activity?)!!.overridePendingTransition(0, 0)
} else
makeToast("Error password not updated")
}
}
else -> {
makeToast("Incorrect old password")
}
}
}
}
I see in the docs how to update your own email once you are logged in, like so:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.updateEmail("user#example.com")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User email address updated.");
}
}
});
What I want, though, is to be logged in as an user and be able to update the email of another user(The logged in user is an admin). With the approach above that's not possible, because you can get only the current user from FirebaseAuth.
Does anyone know how to achieve that?
There is currently no administrative API for Firebase Authentication. We're working on adding this to our server SDKs, but there is no definitive timeline for its availability yet.
I'm using Firebase 9.0.0.
If an user want to change the user email or password, Firebase can throw a FirebaseAuthRecentLoginRequiredException.
firebaseUser.updateEmail(newEmail).addOnCompleteListener(...
In the docs, there is stated to call "reauthenticate(AuthCredential)" in this situation.
In the OnCompleteListener I catch the exception but I'm not able to create the EmailAuthCredential.
How is it supposed to do? From where I take the EmailAuthCredential?
It looks like this is covered here:
Some security-sensitive actions—such as deleting an account, setting a primary email address, and changing a password—require that the user has recently signed in. If you perform one of these actions, and the user signed in too long ago, the action fails and throws FirebaseAuthRecentLoginRequiredException. When this happens, re-authenticate the user by getting new sign-in credentials from the user and passing the credentials to reauthenticate. For example:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
// retry changing the password here
}
});
I've had the same problem with EmailProvider. To reauthenticate, you need credential, and to get credential you need password. I solved it with alert dialog with edit text where user has to enter his password.
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
String reauthenticatePassword = mEditText.getText().toString().trim();
if (!reauthenticatePassword.isEmpty()) {
AuthCredential credential = EmailAuthProvider
.getCredential(firebaseUser.getEmail(),reauthenticatePassword);
firebaseUser.reauthenticate(credential);
}