Welcome to the ninth part of the Firebase Authentication series! In the previous part I showed you how to change a users email in Android Studio with Firebase Authentication. In this part I will show you how to change a users password. A dialog will pop up when a user clicks on the Change password option in the toolbar, where they will be asked to type in the current password, new password, and the new password again for confirmation. Create a new xml file in res/layout and name it dialog_change_password.xml.
dialog_change_password.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/old_password_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Old Password..."
android:inputType="textPassword"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="20dp"/>
<EditText
android:id="@+id/new_password_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="New Password..."
android:inputType="textPassword"
android:layout_marginTop="5dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="5dp"/>
<EditText
android:id="@+id/new_password_again_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="New Password Again..."
android:inputType="textPassword"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:layout_marginTop="5dp"/>
</LinearLayout>
Three EditTexts. One for the current password, one for the new password, and one for the new password again. This view will be inflated in ChangePasswordDialog.java, go ahead and create it and place it in the DialogFragments folder.
ChangePasswordDialog.java
package com.frogitecture.authenticatedgoose.DialogFragments;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.frogitecture.authenticatedgoose.R;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
public class ChangePasswordDialog extends DialogFragment {
public interface ChangePasswordListener {
void onChangePassword(String oldPassword, String newPassword);
}
public ChangePasswordListener listener;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_change_password, null);
final EditText oldPasswordTxt = view.findViewById(R.id.old_password_txt);
final EditText newPasswordTxt = view.findViewById(R.id.new_password_txt);
final EditText newPasswordAgainTxt = view.findViewById(R.id.new_password_again_txt);
builder.setView(view)
.setTitle("Change Display Name")
.setPositiveButton("Change", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String oldPassword = oldPasswordTxt.getText().toString();
String newPassword = newPasswordTxt.getText().toString();
String newPasswordAgain = newPasswordAgainTxt.getText().toString();
if (newPassword.equals(newPasswordAgain)) {
listener.onChangePassword(oldPassword, newPassword);
} else {
Toast.makeText(getActivity(), "Passwords don't match", Toast.LENGTH_LONG).show();
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (ChangePasswordListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(getActivity().toString() + " must implement the listener you silly goose");
}
}
}
We got an interface named ChangePasswordListener
with the method onChangePassword(String oldPassword, String newPassword)
that will be called when the change button is clicked. We check if the two new passwords match to make sure the user doesn't type something wrong accidentally:
if (newPassword.equals(newPasswordAgain)) {
listener.onChangePassword(oldPassword, newPassword);
} else {
Toast.makeText(getActivity(), "Passwords don't match", Toast.LENGTH_LONG).show();
}
If they match, the listener calls its method. In MainActivity.java we make it possible to click on the Change password option in the toolbar. The dialog is shown when this option is clicked.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
...
case R.id.change_password:
ChangePasswordDialog changePasswordDialog = new ChangePasswordDialog();
changePasswordDialog.show(getSupportFragmentManager(),"Change Password");
break;
...
}
}
Next, we need to implement the listener:
public class MainActivity extends AppCompatActivity implements
ChangeDisplayNameDialog.ChangeDisplayNameListener, ChangeEmailDialog.ChangeEmailListener,
ChangePasswordDialog.ChangePasswordListener {
...
}
And the corresponding method:
@Override
public void onChangePassword(String oldPassword, final String newPassword) {
loadingDialog.setMessage("Changing password...");
loadingDialog.show(getSupportFragmentManager(),"Changing Password");
String currentEmail = firebaseUser.getEmail();
AuthCredential credential = EmailAuthProvider.getCredential(currentEmail, oldPassword);
firebaseUser.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
firebaseUser.updatePassword(newPassword)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Password was changed successfully", Toast.LENGTH_LONG).show();
}
loadingDialog.dismiss();
}
});
} else {
Toast.makeText(MainActivity.this, "Authentication failed, wrong password?", Toast.LENGTH_LONG).show();
loadingDialog.dismiss();
}
}
});
}
Here we reauthenticate the user again by checking if the email and the current password the user entered match. If it match and the reauthentication is successful, we call firebaseUser.updatePassword(
newPassword), and the password is changed.
In the next part I will show you how to make it possible for a user to delete his account from this horrible app.
Author
2020-06-22
Changing a display name in Android Studio with firebase auth
Changing email in Android with Firebase Authentication
Deleting an account in Android with Firebase Authentication