Writing a Serverless Android app (ft. Huawei’s AppGallery Connect) — Part 4 — Login and Register
Not read part 3? Read it first!
Over the next couple of months I will be releasing a complete end to end guide to creating an Android app using serverless functionality to completely remove the need for any backend server/hosting etc.
At the bottom of this post you will find my twitch channel where we live stream every Thursday at 2pm BST and the GitHub repo for this project!.
But for those that would rather a written guide, lets get into it!
Today we are going to look at getting the Login and Register process fully complete. This will include some refactoring to the code we have worked on before.
Authentication Manager
With a CloudDBManager now in place that is able to handle the User object we created its time we make changes to the AuthenticationManager so that this CloudDBManager is correctly used to retrieve user data at login/register.
Firstly we have a number of variables that we might be passing into the AuthenticationManager. Up until this point we where only passing in a phone number or an email address and this was handled by the contactString variable. However now that we will be accepting registration information, more data needs to be accept.
When logging in the use may be using their mobile phone number or their email address. When registering they might provide either the phone number or email address or both, and in addition a username and display name.
With these elements in mind lets create a simple data object to store this and pass it into the AuthenticationManager as needed. This will look like below, with standard Getters/Setters and constructor.
We will pass this data into the AuthenticationManager constructor like so:
You will also notice that we have removed the contactString from the construct. As this variable has been removed we should also make sure to remove its usage and replace with the correct data from the LoginRegisterData object.
In places where we where expecting this string to contain the email address we should now use loginRegisterData.getEmail() and in places where we where expecting the phone number we should use loginRegisterData.getPhoneNumber().
Next lets take a look at the getUser() method. Up until now we have simply gotten the AGConnectUser for the currently authenticated user, however we haven’t actually then done anything with that. Now we should use that authenticated user to get the stored User object from the database.
Here we are getting the UID of the authenticated user and then querying the database for the user with that UID.
In the onQuery callback we can check that only one user was returned, and then triple check that the returned user does match the UID. From here we call two new methods saveLoginDetail() and proceedToFeed().
saveLoginDetail() is used to save a local copy of the logged in users ID and set a flag to say that we are now logged in. This way the next time the user opens the application we can check this flag and the user will not have to login every time they open the app.
The proceedToFeed() method will simply start the FeedActivity now that we are logged in.
From the Registration side of the process the only thing to change is the addition of being able to set the username and display name as below.
In the onUpsert call back we use the same two methods saveLoginDetail() and proceedtoFeed() as the login process.
And that’s it! Your AuthenticationManager should now look like this:
Of course as we have now changed the constructor there are some changes that need to be made in both the login and register activities.
Login Activity
Within the MainActivity which is the login activity for us, lets start by creating a simple method to generate the LoginRegisterData object
As you can see we take the email and phone number input and build the object. At this point if we used this method in the phoneLogin and emailLogin onClick listeners we can see there is code duplication. So instead lets extract a method to trigger the login process.
As you can see we generate the AuthenticateManager passing in the LoginRegisterData and the authType. The OnClick Listeners for each button are now just one line calling this method and passing in the AuthType as needed. The MainActivity should now look like this:
Register Activity
For the register activity we do the same process, however we will also add two new EditText fields so that we can accept the user input for username and displayname. Otherwise the process is the same. Create the LoginRegisterData and pass that into the AuthenticationManager. This this in mind the Register activity will look something like:
And that’s it! we are now in a good state with the login and register flow which will result in a user being authenticated, logged in and use saving the ID of that user along with setting a flag to confirm the user is logged in.