Not read part 2? Read it first!
Writing a Serverless Android app (ft. Huawei's AppGallery Connect) - Part 2 - CloudDB
Zachary Powell ・ Jul 14 '21
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!
Last time we looked at the basic setup of the CloudDB service, how to get things configured and how you can get started with the service. Now this is in place lets take a look at the service in more detail. We started working on a CloudDBManager
that was going to handle all the communication between the CloudDB service and the rest of the app. This was a great start but before we dig any deep lets look at a few improvements to this.
Listen for Database Changes
In the current CloudDBManager
if we want to check for any changes to the database we had to manually call getAllUsers()
. This is fine if we aren't really interested in when changes are made to the database, however if we do want to keep an up to date local copy of the data (for example posts in a feed) we need to look at adding a Snapshot Listener. This will tell the CloudDB service to execute a given query and process the results in real time.
Lets start by defining a new OnSnapShotListener
for the Class User
when the listener is given a snapshot we pass this into the processResults
method we created last week.
private final OnSnapshotListener<User> snapshotListener = (cloudDBZoneSnapshot, e) -> processResults(cloudDBZoneSnapshot);
Next we create a method that will subscribe that Snapshot Listener to the CloudDBZone with an applied query, in this instance just the simple query to return all Users
public void addSubscription() {
CloudDBZoneQuery < User > snapshotQuery = CloudDBZoneQuery.where(User.class).equalTo("uid", "");
try {
ListenerHandler handler = cloudDBZone.subscribeSnapshot(snapshotQuery,
CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY,
snapshotListener);
} catch (Exception e) {
toaster.sendErrorToast(context, e.getLocalizedMessage());
}
}
With this in place we can now tweak the openCloudDBZone
method, by using a task based approach we are able to add an onSuccessListener. So long as the zone is successfully opened we can called the addSubscription()
method and start listening for new data.
public void openCloudDBZoneV2() {
CloudDBZoneConfig config = new CloudDBZoneConfig("Barker",
CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC);
config.setPersistenceEnabled(true);
Task < CloudDBZone > task = cloudDB.openCloudDBZone2(config, true);
task.addOnSuccessListener(zone - > {
cloudDBZone = zone;
addSubscription();
}).addOnFailureListener(e - > toaster.sendErrorToast(context, e.getLocalizedMessage()));
}
Use userList
In the processResults
method from last week we took the data snapshot and converted it into a list of User objects. We didn't then do anything with this nor did we have a method to pass that data onto somewhere else in the app. Lets change that!
We will start by creating a new public interface called UserCallBack
this will be implemented by any class that wants to use an instance of the CloudDBManager. Currently the interface is pretty simple with just three methods:
public interface UserCallBack {
void onAddOrQuery(List < User > userList);
void onDelete(List < User > userList);
void onError(String errorMessage);
}
We create a variable for this Call back within the CloudDBManager
like:
private final UserCallBack callBack;
And finally as part of the CloudDBManager
init method we require an instance of the UserCallBack
public CloudDBManager(Context context, UserCallBack callBack) {
cloudDB = AGConnectCloudDB.getInstance();
this.context = context;
this.callBack = callBack;
}
Now when we have processed the result of a query we can pass that data back to the calling class using the callback. For example the processResult
method now looks like:
private void processResults(CloudDBZoneSnapshot < User > userCloudDBZoneSnapshot) {
CloudDBZoneObjectList < User > userCursor = userCloudDBZoneSnapshot.getSnapshotObjects();
List < User > userList = new ArrayList < > ();
try {
while (userCursor.hasNext()) {
User user = userCursor.next();
updateMaxUserID(user);
userList.add(user);
}
callBack.onAddOrQuery(userList);
} catch (AGConnectCloudDBException e) {
callBack.onError(e.getLocalizedMessage());
toaster.sendErrorToast(context, e.getLocalizedMessage());
} finally {
userCloudDBZoneSnapshot.release();
}
}
We now have a way to both pass back the user list and also any error message that might be given during the processing!
The final CloudDBManager
should look something like:
Authentication Manager
With the changes made above lets take a look at how we can use this to gain access to the database data. Specifically within the AuthenticationManager
.
First we must now implement the new interface like so:
public class AuthenticationManager implements CloudDBManager.UserCallBack{
...
@Override
public void onAddOrQuery(List<User> userList) {
}
@Override
public void onDelete(List<User> userList) {
}
@Override
public void onError(String errorMessage) {
}
...
}
The onAddOrQuery
method will be given the userList returned when a snapshot is processed, we can implement code here to update the UI or confirm if a user is already registered for example.
In this Classes init method we will also need to pass itself in as the UserCallBack
. The setup of the CloudDBManager
object will now look like:
dbManager = new CloudDBManager(context, this);
dbManager.createObjectType();
dbManager.openCloudDBZoneV2();
We are now in a good position to query data, view it and upsert it! Join us next week when we start configuring the other Objects we are going to be using, expand the User object and make the CloudDBManager
generic for any CloudDB Object!
Twitch Account
Github Repo
devwithzachary / Barker
Project init
Barker - A Serverless Twitter Clone
Barker is a simple twitter style social network written to demostrate the serverless services provided by Huawei's AppGallery Connect platform.
This app is written during live streams over at https://www.twitch.tv/devwithzachary The streams are then edited down into videos which you can watch https://www.youtube.com/channel/UC63PqG8ZnWC4JWYrNJKocMA
Finally there is also a written copy of the guide found on dev.to https://dev.to/devwithzachary
Each episodes code is commited as a single commit to make it easy to step along with the code, simply checkout the specific commit and follow along!
We will be back with the next part next week!
Top comments (0)