Writing a Serverless Android app (ft. Huawei's AppGallery Connect) - Part 4 - Login and Register
Tags: android, java, serverless, appgallery
Published: 2021-08-25 15:34:25

Not read part 3? Read it first! {% link https://dev.to/devwithzachary/writing-a-serverless-android-app-ft-huawei-s-appgallery-connect-part-3-more-clouddb-34o8 %}

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!.

{% youtube ImdiOsM7Naw %}

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.

{% gist https://gist.github.com/devwithzachary/9f98e7af93152f22066aa126ad3461ff %}

We will pass this data into the `AuthenticationManager` constructor like so:

{% gist https://gist.github.com/devwithzachary/f475fd7ab82b7fd7125048cb3c623a3f %}

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.

{% gist https://gist.github.com/devwithzachary/947da132d42271f71758351378502367 %} 

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. 

{% gist https://gist.github.com/devwithzachary/43bac6f899ae05039cfe75dd76de6942 %}

The `proceedToFeed()` method will simply start the `FeedActivity` now that we are logged in. 

{% gist https://gist.github.com/devwithzachary/78cd2afa4ecf04204deb97cdfc76a59b %}

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. 

{% gist https://gist.github.com/devwithzachary/d61951fdd4d7ad46fccd17f8436c97cb %}

In the `onUpsert` call back we use the same two methods `saveLoginDetail()` and `proceedtoFeed()` as the login process.

{% gist https://gist.github.com/devwithzachary/d55ce41ba93e389d53e729c5860d4915 %}

And that's it! Your `AuthenticationManager` should now look like this:

{% gist https://gist.github.com/devwithzachary/97e23d7c813fd917a13ab88de34f9751 %}

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

{% gist https://gist.github.com/devwithzachary/52b28e6fbec37e6acd0cc3f95945c50f %} 

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.

{% gist https://gist.github.com/devwithzachary/ac5d8bc0984c36837bc586d7b895c091 %} 

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:

{% gist https://gist.github.com/devwithzachary/b9cb25f1b86b0503a5f4883345201b9d %}

#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:

{% gist https://gist.github.com/devwithzachary/10a3837b0e9abbc32e1b3dcf083f4276 %}

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.

#Twitch Account

{% twitch devwithzachary%}

#Github Repo

{% github devwithzachary/Barker%}

We will be back with the next part next week!