Managing User Accounts using the Firebase SDK
The previous chapter demonstrated the use of the authentication features of the Firebase SDK to provide email and password-based account creation and sign-in features for Android apps. In addition to providing the ability to create and sign into accounts, it is also important to gain an understanding of the account management features provided by the Firebase SDK, including the ability to change a user’s email address or password, delete accounts and add user profile information such as a display name and photo. The goal of this chapter is to outline these account management features including sample code designed to work with the example created in the previous chapter.
Enhancing the User’s Profile Information
When a new email and password based account is created using Firebase SDK authentication no display name or profile photo is initially assigned to the user’s account. Once the account has been created, however, these properties may be assigned to the account by creating a UserProfileChangeRequest object containing a display name and photo Uri and then passing this object through to the updateProfile() method of the current user object.
Assuming a profile photo image named photo.jpg located in the app -> res -> drawable location within the project, the following code would assign this image as the profile photo along with a display name of “Ann D. Roid” within the profile of the current user where <your pkg name here> is replaced by the package name for your project (for example com.example.firebaseauth):
FirebaseUser user = fbAuth.getCurrentUser(); UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder() .setDisplayName("Ann D. Roid") .setPhotoUri(Uri.parse( "android.resource://<your pkg name>/drawable/photo")) .build(); user.updateProfile(profileUpdates) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Toast.makeText(FirebaseAuthActivity.this, "Profile updated.", Toast.LENGTH_SHORT).show(); } });
Changing a User’s Email Address
It is not uncommon for a user to want to change the email address associated with an account. This feature can be added to an app by making a call to the updateEmail() method of the current user object, passing through as an argument the new email address. It is important to note that this method call will only work if the user is already signed in. The code to implement this reads as follows:
String email = emailText.getText().toString(); FirebaseUser user = fbAuth.getCurrentUser(); user.updateEmail(email) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Toast.makeText(FirebaseAuthActivity.this, "Email address updated", Toast.LENGTH_SHORT).show(); } } });
When a user successfully changes the email address associated with an account, the Firebase authentication system will send the user an email to the old email address containing notification of the change and providing a link to reverse the update. The default template for this email may be modified within Email Templates screen of the Authentication section of the Firebase console by selecting the Password Reset category followed by the edit button as indicated in Figure 11-1:
Figure 11-1
For details on customizing this message, refer to the earlier chapter entitled Testing and Customizing FirebaseUI Auth Authentication.
11.3 Changing a User’s Password
Not to be confused with the password reset option, this feature of the Firebase SDK allows the password of a currently signed in user to be changed from within a running app. This involves a call to the updatePassword() method of the current user object passing through the new password as an argument. In common with other Firebase SDK methods a completion handler may be assigned to receive notification of the result of the request.
String password = passwordText.getText().toString(); FirebaseUser user = fbAuth.getCurrentUser(); user.updatePassword(password) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Toast.makeText(FirebaseAuthActivity.this, "Password updated", Toast.LENGTH_SHORT).show(); } } });
Deleting a User Account
The currently signed-in user’s account may be deleted from the Firebase Authentication system via a call to the delete() method of the current user object as follows:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); user.delete() .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Toast.makeText(FirebaseAuthActivity.this, "Account deleted", Toast.LENGTH_SHORT).show(); } } });
Verifying the User’s Email Address
When using email and password authentication it usually makes sense to take some steps to verify that the email address provided actually belongs to the user. The best way to do this is to send an email to the provided address containing a verification link. Until the user has clicked the link, access to the app can be denied even though an account has been created.
To instruct Firebase Authentication to send a verification email, simply call the sendEmailVerification() method of a FirebaseUser instance as follows:
FirebaseUser user = fbAuth.getCurrentUser(); user.sendEmailVerification() .addOnCompleteListener(this, new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { // Verification sent successfully } else { // Failed to send verification email. } } });
When the user subsequently attempts to sign into the app, code can be added to check that the user’s email address has been verified by calling the isEmailVerified() method of the FirebaseUser instance:
if (user.isEmailVerified() == true) { // User has verified email address } else { // User has not verfified email address }
The template for the email address verification email may be modified within the Firebase console by selecting the Templates tab in the Authentication screen and selecting the Email address verification category.
Understanding Security Sensitive Actions
With the exception of making updates to the user’s profile information, each of the account management tasks outlined in this chapter are categorized as security-sensitive actions. Although all of the actions outlined above require that the user be signed into the account for which changes are being made, security-sensitive actions impose the additional requirement that a limited amount of time must have elapsed since the user signed into the account. If this time restriction has been exceeded, the method calls to delete or update the accounts will fail with an exception.
One option would be to force the user to sign out of the app and then sign back in before performing a security sensitive action. Fortunately, the FirebaseUser class includes a method named reauthenticate() which can be used to refresh the user’s credentials when making a security-sensitive account change. In order to know when re-authentication is required, however, it is important to be able to detect and identify authentication failure exceptions, a topic which will be covered in the next chapter.
Summary
There is more to user authentication than simply creating user accounts and providing a sign-in interface. Users also need to be given the ability to make changes to, or even delete, their accounts. Fortunately, the FirebaseUser class provides a range of methods that allow such features to be integrated into Android apps with relative ease.
With the exception of profile updates, all of the management tasks outlined in this chapter are considered to be security-sensitive, requiring user re-authentication if too much time has elapsed since the user signed in. Detecting and responding to this situation, along with other authentication failures will be covered in the next chapter.