HUAWEI Ability Gallery — Account Binding with Native Android & Java Spring

Kadirtas
Huawei Developers
Published in
9 min readJun 14, 2021

In today’s world, with the development of technology, the acceleration of transactions has made us even more impatient than expected. Although processes that used to take very long now decrease to seconds, sometimes we can stop using some applications even when there is a millisecond delay. For this reason, even fractions of a second are very important for applications that try to keep up with today’s world, in order not to lose users.

For example, let’s say a user controls the market in a trading application. For this, there are many processes such as finding the application and waiting for the splash screen stage, then logging in, waiting for the result of the request. In this scenario, considering that the user does this about 20 times a day, it would be a real waste of time. For this reason, loss of users will be inevitable.

For this reason, we can create widgets on the -1 screen of our applications, thanks to features such as Card Ability or Content Ability provided by the Huawei Ability Gallery, and enable application users to access more specific information from there. In this way, we can not only get rid of this loss of users, but also gain new users.

In this article, I will talk about the account binding process in order to synchronize the data of our users with the Card Ability feature provided by the Huawei Ability Gallery(HAG). I will try to explain how the process is done on the technical side.

Note: I recommend you to read this article for console side operations and more theoretical information.

Account Binding has 2 different methods. In the first method, account binding is done for applications that have the developer’s own sign-in method without using Huawei ID. In the second method, account binding is done using Huawei ID. In this way, we synchronize the data of our users with our widget and application on the “-1” screen.

So what is the difference between these two methods?

In the scenario where account binding is done using Huawei ID, the client can always obtain OpenID since there is an Auth Service on the client side. And it can sync according to this id. For this reason, we do not need to keep the userID and OpenID pair in the DB. Because when we want to synchronize, OpenID is obtained by the client thanks to the Auth service, and when we send OpenID to the backend, we can provide synchronization since we have already recorded it in the DB. There is no need to keep an extra userID in the backend.

However, in the scenario that we will do in this demo, namely the Account Binding scenario where we use our own sign-in method without using Huawei ID, the Client cannot obtain the OpenID because there is no Auth Service. However, OpenID can be obtained with deeplink only in the first account binding stage. For this reason, we save the userId and OpenID pair so that we can synchronize without asking the client for OpenID again. Because only when we send the userID to the backend, we can synchronize according to this userID. We do this by reporting the OpenID corresponding to the incoming userID to the HAG server, according to the userID openID pair in the backend.

In addition, you can see the difference between account binding without using Huawei ID with Custom sign-in method and account binding using Huawei ID in the application in the diagram below.

Note: In this diagram, I have numbered step 5 as the first step, to avoid confusion with the steps in the demo part and the implementation process steps in the official document, and because it is the beginning of the topic of this article.

In order to better explain how to do Account Binding according to Developer’s own sign-in method without using Huawei ID, we will make a demo with Native App on the client side. In the backend, we will use Java Spring. Now we can move on to the development stages.

Development

In this demo, we will use Account Binding in an e-commerce application scenario. In this way, we will bind the user’s account with Account Binding to the widget we use Card Ability feature on the -1 screen.

Using Account Binding, we will be following the implementation process below to bind users’ accounts. However, in addition to this, I should add another step and specify that we need to perform server side authentication. Because we will need an access token in the header when declaring the Account Binding process to the HAG server.

Now I want to talk about what we will do step by step. You can think of this explanation as an overview. Afterwards, I will explain the codes to be written at each stage. You can follow the diagram above in order not to get lost during the explanation. Because we will proceed according to this diagram.

Since we’re going to talk about server-side and client-side improvements here, we’ll start from step 5. First of all, an OpenID comes to our server by Huawei Ability Gallery. We need to respond to the incoming request with a deeplink with this OpenID. This deeplink should be the sign in page of our application. When HAG runs this deeplink, the sign in page of our application comes up. Here we expect the user to sign in so that our uuid and OpenID match are not wrong. So we want to match the correct user id. After the user signs in on the sign-in page opened in the application, we send the user’s ID and the OpenID received via deeplink to our server to match. Finally, after the match process, we need to report the result to the HAG server. And in this way, we complete the Account Binding.

What we have achieved as a result is linking our users’ accounts to the Card Ability widget provided by the Huawei Ability Gallery on the -1 screen.

Now for the first step (for the 5th step, which is our beginning), we must first define a deeplink on the client side. Since we are using Navigation Component in this demo application, we add a deeplink tag inside the sign in fragment tag in our navigation_main.xml file.

Then we add our nav graph inside the activity tag in our manifest file.

<nav-graph android:value="@navigation/sign_in_graph"/>

Now we send this deeplink to HAG server. In this way, HAG will run this deeplink on the user’s device and redirect the user to the sign in page of our application.

For this, we need to prepare the endpoint that HAG will request to receive the deeplink. Now we need to go to the backend side and write the Controller here. However, we must first create the classes and interfaces that we will use in this Controller. When connecting the controller and the service, we will use interfaces to facilitate testability and to create a better structure. For this, we first create our HAGServiceinterface.

Here, I added all the functions that we will use in the future in order not to add this interface again and extend the article. However, for step 5 we will only use the getLoginDeeplinkfunction for now.

Now let’s create the AccountBindingHAGDeeplinkRequestobject, which is the parameter of this function. Since we only need OpenID in the demo we will do here, AccountBindingHAGDeeplinkRequestmodel can be as follows (I am sharing the json file instead of java classes since creating separate objects will take up a lot of space. You will need to create classes to represent this json file while you are developing. ):

Also, we must create a response class that HAGServer will accept. I write the json object because I don’t want to write all the nested classes below and extend the post. However, you need to create objects to represent this json file.

Note: Remember, the name of the class properties you will create must be exactly the same as those in the json file, as it will be object mapping.

AccountBindingHAGDDeeplinkResponse.java (json representation) :

Note that each property is case sensitive here and “reply”, “accountLoginAddr” and “deepLink” are nested objects. Also, we should not forget that the type of “minVersion” is Long.

Note that each property is case sensitive here and “reply”, “accountLoginAddr” and “deepLink” are nested objects. Also, we should not forget that “minVersion” is of type Long.

Note: For other properties and their types you can check this link.

Now let’s write our HAGServiceImplclass, where we will get the OpenID from the request in the format we created and we will do the response message creation in the format we created. This class will implement the HAGService interface.

Here, objects like AccountBindingHAGReply are the objects I created to represent the json object.

When creating a response message, we must fill it with the following values:

  • version: “1.0”
  • url: We add the deeplink we defined to the sign in page of our application and the OpenID from the request at the end.
  • appPackage: package name of our app
  • minVersion: 1l
  • errorCode: “0”
  • errorMessage: “ok”

We will connect our created service implementation class to the Controller. We will send the request to get the deeplink of the sign in page that comes to the controller to here, and return the response message in the format that the HAG Server will receive.

Now let’s create our Controller:

Here we autowired our service class that we wrote in the previous step. Since HAG server will send a POST request to the url we will specify on the console side, we have added the @PostMapping annotation to the accountBinding method where we will handle this request. Since the HAG server will send the OpenID here in the body and in the request object format that we created before, this function should take the request object we created as a parameter, with the @ResponseBody annotation at the beginning. In this way, after we create our function, we pass the incoming parameter to the service we created and get the prepared response object with deepLink and return it.

Note: According to this function and Controller, the url we need to specify for account binding in HAG console should be “ ‘your domain’ /hag/account/bind”.

From here on, HAG will open the sign in page of our application by running the obtained deeplink, which is step 6 in our implementation process diagram, with the OpenID at the end. In step 7, the user will enter the account information here. If the sign in process is successful, we will send together the OpenID and user id we obtained with the deeplink to our backend as step 8.

Note: Since we will be making http requests using retrofit in a standard way here, I do not include client-side operations to avoid prolonging this blog. However, after you sign in successfully, you can send the user’s ID and OpenID to your backend based on your own backend implementation.

As the 9th step, we will save the id matches to our database. Here, after creating the Repository and performing the necessary verification steps according to your backend, we complete the writing process to the database. As the 10th step, we report it to the HAG server. For this, we send a request to the account binding url of the HAG server using WebClient. For this request, we must first get the Bearer token we need in the header. We will use WebClient again in order to request a Bearer token.

We are creating a form data because the url content type we will receive tokens supports url-encoded. This form data should contain grant_type, client_id and client_secret values as above. Here, the fields that you need to fill in according to your own project are as follows;

  • client_id
  • client_secret

You can access these values from the console.

Then, we get the Bearer token we need in the header of the request of account binding by sending a POST request to TOKEN_URL using WebClient.

Now we have to create the body of the request that we will send to the HAG server to report the account binding result.

Finally, we will request to declare the account binding status to the HAG server with the values we will obtain using these functions.

Here, the parameter openID comes from the id match request thrown from the application.

In this way, users of our application will be able to connect their accounts with the Card Ability feature provided by the Huawei Ability Gallery.

For Unbind, we only need to change the BIND_URL. All remaining operations are the same.

Unbind URL: https://hag-eu.cloud.huawei.com/open-ability/v1/open-account-events/unbind

--

--