AppGallery Connect Remote Configuration: Spice up your app without the fuss

This blog will show you how to use Remote Config to toggle app features based on a remote setup. Using Huawei’s AppGallery Connect we can leverage user attributes and remote conditions to quickly and easily modify parameters from the cloud.

AppGallery Connect Remote Configuration: Spice up your app without the fuss

As an app developer, your app may need to provide user with fresh content
and functions to keep them interested and tailor the app experience to fit
everyone’s needs, that’s where Remote Configuration comes in.

In conclusion, AppGallery Connect Remote Configuration can:

Modify parameters over the cloud, so apps installed on devices can periodically fetch parameter updates from the cloud, not requiring users to update the app and therefore accelerating app rollout.

This blog will show you how to use Remote Configuration to toggle app
features based on a remote setup. Using Huawei’s AppGallery Connect we
can leverage user attributes and remote conditions to quickly and easily
modify parameters from the cloud.

As a quick comparison to the Android developer usual tool chain. You can think of AppGallery Connect (AGC) as the equivalent of Firebase. Therefore when I talk about the AGC console you can compare that to the Firebase console. In both consoles you have access to features such as analytics, crash analytics, remote configuration, push notifications with deep linking, in app messaging and a whole lot more!.

If you have used Firebase Remote Config, Huawei AGC Remote Configuration is just as simple to use. If you haven’t used Firebase that doesn’t matter! AGC Remote Configuration has an intuitive and simple API. The example application written for this blog post is available open source on GitHub here.

With that .. let’s .. get .. started!

Sign in/up to AppGallery Connect

First thing that needs to be done is for you to sign up and/or in to AppGallery Connect and verify your identity (can take up to 3 days, so plan for this). Ensure you have a Project and an App created that you can work in. If you haven’t done that before, you can read more about it here.

Once that is done, you will have access to the console that looks something like this:

Build Application that uses Remote Configuration

We’re going to build an application that uses Remote Configuration to decide how to layout it’s User Interface. The AGC Academy has a video explanation here. This is a typical Remote Configuration use case, perhaps more usually you would switch out whole features, or change navigation paths to toggle features on and off, but here to keep the tutorial simple, we will toggle some text and change the background color.

The app using Remote Config once complete.

Through Remote Configuration there are a range of functions that can be applied such as diverse filters, historical version management and real-time updates.

In analytics you have something called “User Attributes” these are specific details about a user or a users behaviour that can help you differentiate and segregate groups of users. AGC Analytics has a built in User Attribute called “Country/Region” and this allows you to group your users based on the IP address of the network hardware their phone last connected to.

For example then, say you had a football (soccer) application, you could show supporters who “are from” Scotland the Scottish flag in your UI on the main screen and those in England the English flag. This may have some IP edge cases along the Scotland/England border which is an issue, but a bigger issue would be Spanish people who are just visiting Scotland for a holiday! We can fix this issue with something called custom User Attributes.

Creating a custom user attribute for ‘country’ would allow you to determine where the person is from based on something other than IP. In our demo we have an EditText on the screen and you can type in a country name (in a real world scenario you wouldn’t type this in, but perhaps infer it from the active SIM ISO or the Device set Locale, or perhaps you could have the user select it from a list.

Configure Remote Configuration Console Settings

To create this custom user attribute, go to the AppGallery Connect console > Huawei Analytics > User Attributes and press ‘create’. You are then asked for an ID, Name & Description. Name and Description are for human purposes only, the ID will be used as the key so that we can read/write this user attribute from our app.

Set the following values:

  • ID = “country”
  • Name = “Country”
  • Description = “The country we have determined they are currently in.”

It will look something like this when you are done:

Now that we have our custom user attribute created. We can use it for filtering from our Remote Configuration.

Again go to the AppGallery Connect console > Grow > Remote Configuration, select the “Conditions” tab and then press the “New condition” button. You are then asked for a Condition and a Description, below that is a dropdown where you can select the condition that will be used for the filter. Set the following values:

  • Condition = “Country UK”
  • Description = “True when the User Attribute of country is set to the UK.”
  • Select = “User Attributes” > Country > Equal > “UK”

It will look something like this when you are done:

Hit “save” and navigate back to the “Parameters” tab.

We are going to make two parameters, the first will be a standard remote configuration toggle that will be a boolean set in the console true or false. The second will also be a boolean toggle, however the true or false will be determined on the condition we just made.

Press the “new parameter” button to create these values. You are then asked for “Parameter” which is the name of the key we will use to reference this remote configuration parameter in our app. A “default value” which can take JSON or any primitive value type (such as String, Int etc). And a “description” to remember what this value is for.

For the first feature toggle set the following values:

  • Parameter = “enable_feature_1234_cool” (try and use a common naming scheme)
  • Default value = “false”
  • Description = “True to enable Feature 1234. This will turn on this cool new feature.”

For the second feature toggle set the following values:

  • Parameter = “enable_feature_1235_theme” (try and use a common naming scheme)
  • Default value = “false”
  • Description = “True to enable Feature 1235. This will turn on the theme feature.”
  • Add Conditional Value > Condition = “Country UK”, Value = “true”

It will look something like this when you are done:

Setup and Initialise App

Now that all the console configuration is done, we can get on with creating the Android app! If you still haven’t added the AppGallery Connect services to your Android app (by including the plugin and services json file), you can read more about it here. You may recognise this pattern. This is the same process as you have to do the first time you add Firebase to your project. The example project is also setup this way, adding the agconnect plugin to do the json parsing of your config.

/build.gradle:

buildscript { 
  repositories { 
    ...
    maven {url 'https://developer.huawei.com/repo/'} 
  } 
}

buildscript { 
  dependencies { 
    ...
    classpath 'com.huawei.agconnect:agcp:1.5.2.300'
  } 
}

/app/build.gradle:

dependencies {
  implementation 'com.huawei.agconnect:agconnect-core:1.5.2.300'
  ...

Create Remote Configuration in App

To use Remote Configuration with User Attributes, the remote configuration and hi analytics need to be added as dependencies to your project:

dependencies {
  ...
  implementation 'com.huawei.agconnect:agconnect-remoteconfig:1.5.2.300'
  implementation 'com.huawei.hms:hianalytics:6.0.0.300' 
  ...

Next we create a layout that allows us to show and edit the ‘country’ User Attribute. We add a TextView to show the status of our 1234 feature, and a Button to force a refresh of the currently fetched remote configuration. We ensure the root view has an ID so we can change it’s background color.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <TextView
        android:id="@+id/text_explanation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This would usually be a value hidden from the user. But for the sake of the demo you can change it here. Refresh the config after changing the value. User country:"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="User country (try 'Spain' or 'UK'):"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/text_explanation">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/edit_text_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Spain" />

    </com.google.android.material.textfield.TextInputLayout>

    <TextView
        android:id="@+id/text_view_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onRefreshConfigClick"
        android:text="Refresh Remote Configuration"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

The XML layout we just created.

To use the Remote Configuration we need an instance of AGConnectConfig (api doc), and to get/set the UserAttributes we use an instance of HiAnalyticsInstance (api doc).

private lateinit var config: AGConnectConfig
private lateinit var analytics: HiAnalyticsInstance

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    config = AGConnectConfig.getInstance()
    analytics = HiAnalytics.getInstance(this)
    ...

When the UI loads, we want the EditText to show the current Country User Attribute, and when the button for refreshing is pressed, we want to save the Country that was typed last. In the HiAnalyticsInstance API a UserAttribute is called a UserProfile.

val currentCountry = analytics.getUserProfiles(false)["country"] ?: "Spain"

val editTextOne: EditText = findViewById(R.id.edit_text_one)
val currentCountry = editTextOne.text.toString()
// This sets the custom UserAttribute 'country' we created in the console
analytics.setUserProfile("country", currentCountry)

We are now setting the users country whenever it changes, this means if we fetch the remote configuration for “enable_feature_1235_theme” it will take into account what country they are in when sending us back true or false. In comparison if we fetch “enable_feature_1234_cool” is will always return ‘false’ since we set it to that explicitly in the console. This is how you fetch both those boolean values with Remote Configuration:

val enableFeature = config.getValueAsBoolean("enable_feature_1234_cool")
val textView: TextView = findViewById(R.id.text_view_one)
if (enableFeature) {
    textView.text = "Feature Enabled! (Go to the console to toggle this)"
} else {
    textView.text = "Feature Disabled! (Go to the console to toggle this)"
}

val enableFeature1235 = config.getValueAsBoolean("enable_feature_1235_theme")
val contentMain: ViewGroup = findViewById(R.id.content_main)
if (enableFeature1235) {
 contentMain.setBackgroundColor(Color.parseColor("#22FF0000"))
 Toast.makeText(this, "Welcome to the UK!", Toast.LENGTH_SHORT).show()
} else {
 contentMain.setBackgroundColor(Color.parseColor("#2200FF00"))
 Toast.makeText(this, "Goodbye!", Toast.LENGTH_SHORT).show()
}

Finally we will force a refresh of the remote configuration when the button is pressed. This isn’t usually necessary in a production app, as you would have a sensible refresh period and the library automatically for you will check for updates to this config. But for demo purposes we want to force a refresh so we can see how changing the country has an affect.

config.fetch(0) // a value of 0 here is for DEBUGGING ONLY, delete for prod (giving a 12 hour refresh period)
    .addOnSuccessListener {
        config.apply(it)
        Log.d(TAG, "Applied")
        updateUIBasedOnRemoteConfig()
    }

Conclusion

That’s it! All the code you see above is available on GitHub here. You have been able to use AppGallery Connect console to create a Remote Configuration that takes into account custom User Attributes, and use this to toggle features on and off within your application. It supports SDK integration with only a few of code lines, you can easily access the service.

What’s more, AppGallery Connect services can be used for Android, web,
and quick apps with cross-platform framework, including Flutter,
Cordova, and React Native.

Full disclosure notice: I have written this post in partnership with Huawei and they are excited to announce AppGallery Connect Academy and encourage the use of AppGallery Connect.

Huawei AppGallery Connect has an Academy of training here, with material available as written articles, documents as well as video explanations to help you get to grips with these great features. There is a lot more including AB Testing, In App Messaging, App Deep Linking and more ways to use Remote Configuration.