Change password with Firebase for Android
Asked Answered
C

8

33

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?

Callery answered 5/10, 2016 at 5:32 Comment(1)
try this<androidhive.info/2016/06/…>.Hildegard
C
72

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("[email protected]", "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")
                }
            }
        });
Callery answered 1/12, 2016 at 7:8 Comment(0)
W
23

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();
                        }
                    }
                });
            }
        }
Wynd answered 13/1, 2017 at 14:23 Comment(0)
H
17

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.

Hypophyge answered 5/10, 2016 at 13:42 Comment(0)
A
7

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.
});
Adenoid answered 26/11, 2019 at 1:1 Comment(1)
This could be very helpful for people using VueJS, but it does not really answer the question, since the question is about Android. Could you translate the answer to be valid for Android? You can also open new question for VueJS, and post this answer there to help people with the same problem in VueJS.Zareba
A
2

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 protected]");

begin by initializing

    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;
    private String DummyEmail = "[email protected]"

    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.

enter image description here

The content will look something like this

enter image description here

the reset link will prompt the following dialog on a new web page io

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

enter image description here

Abecedary answered 11/2, 2017 at 10:35 Comment(1)
„the reset link will prompt the following dialog on a new web page” - what's next? I mean, which method I should use to setup a new password?Setback
S
1

A simple approach to handle changing a password is to send a password reset email to the user.

FirebaseAuth.getInstance().sendPasswordResetEmail("[email protected]")
    .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();
            }
    });
Shoat answered 8/6, 2020 at 17:20 Comment(0)
D
1

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")
            }

        }
    }
}
Disclaim answered 3/12, 2022 at 9:2 Comment(0)
Y
0

In the latest version of Firebase you need to get the latest authentication from Firebase to change the password (for which you have to request re-authentication from Firebase), if the authentication is valid and up to date, then you can change the password you have, here I include the implementation code to change password.

In Kotlin:

private fun changePassword(email: String, oldPassword: String, newPassword: String) {
    val user = FirebaseAuth.getInstance().currentUser

    user?.let {
        val credential = EmailAuthProvider.getCredential(email, oldPassword)

        it.reauthenticate(credential).addOnCompleteListener { task ->
            if (task.isSuccessful) {
                it.updatePassword(newPassword).addOnCompleteListener { task ->
                    if (task.isSuccessful) {
                        Toast.makeText(this, "Password changed successfully", Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this, "Error changing password: ${task.exception?.message}", Toast.LENGTH_SHORT).show()
                    }
                }
            } else {
                Toast.makeText(this, "Error reauthenticating: ${task.exception?.message}", Toast.LENGTH_SHORT).show()
            }
        }
    } ?: Toast.makeText(this, "No user is currently logged in", Toast.LENGTH_SHORT).show()
}

In Java:

private void changePassword(String email, String oldPassword, String newPassword) {
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    if (user != null) {
        AuthCredential credential = EmailAuthProvider.getCredential(email, oldPassword);

        user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    user.updatePassword(newPassword).addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                Toast.makeText(getApplicationContext(), "Password changed successfully", Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(getApplicationContext(), "Error changing password: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                } else {
                    Toast.makeText(getApplicationContext(), "Error reauthenticating: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        });
    } else {
        Toast.makeText(getApplicationContext(), "No user is currently logged in", Toast.LENGTH_SHORT).show();
    }
}
Yusem answered 24/7, 2024 at 19:28 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.