Android

Real time application using Live Queries

Introduction

Live queries are meant to be used in real-time reactive applications, where just using the traditional query paradigm would come with some problems, like increased response time and high network and server usage. Live queries should be used in cases where you need to continuous update a page with fresh data coming from the database, which often happens in, but is not limited to, online games, messaging clients and shared to do lists.

This section explains how to use Back4App’s Live Query in an Android environment through Back4App.

For this tutorial, as an example, you will build an Online Poke System using Live Queries, as shown below:

User Registration with Face7book Login App

See the complete example project at Live Query - Online Poke System Project.

See more about Parse SDK at Android SDK API Reference and Parse open source documentation for Android SDK.

Prerequisites

To complete this tutorial, you need:

Step 1 - Enable Live Query

Before you start coding, it’s necessary to have a class in your database to enable Live Query. To do that, simply find your app at Back4App website, and click on Dashboard > Create a class, as shown here:

Note: Here, this class will be called Message.

Now, to enable Live Query feature, log in to your account at Back4App website, find your app and click on Server Settings, then find the “Web Hosting and Live Query” block and click on SETTINGS.
The “Web Hosting and Live Query” block looks like this:

Then, you will arrive at a page like the one below. At this page you will need to check the Activate Hosting option, the Activate Live Query option and all the classes you want Live Query to be activated, as shown below:

It’s necessary to activate WebHosting to use Live Queries, because your domain will work as the live server.

Step 2 - Set up the LiveQuery client

Parse Server’s Official GitHub have an implementation of the Live Query Client for Android. It is necessary to implement the official Live Query client, which works nicely. To do so, add the following lines to your app build.gradle file, in the dependencies section:

app/build.gradle

1
2
3
4
5
6
7
dependencies {
    ...
    // Don't forget to change the line below with the latest version of Parse SDK for Android
    implementation "com.github.parse-community.Parse-SDK-Android:parse:1.18.5"
    implementation 'com.github.parse-community:ParseLiveQuery-Android:1.1.0'
    ...
}

Then you need to import the LiveQueryClient from liveQuery package. Add the following imports:

LiveQueryExampleActivity.java

1
2
import com.parse.livequery.ParseLiveQueryClient;
import com.parse.livequery.SubscriptionHandling;

In this project, we will also create a class named Message, which will advertise the poke action. This class contains two columns, named content and destination.

Step 3 - Subscribe to your query

To start using Live Queries, first create a LiveQueryClient that will manage the WebSocket connections for you. To do this, you will have to provide the application ID, its JavaScript Key and also a server URL that should be the domain with which you did the setup in the first step.

The code for initializing LiveQueryClient is the following:

liveQueLiveQueryExampleActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Back4App's Parse setup
Parse.initialize(new Parse.Configuration.Builder(this)
    .applicationId("APPLICATION_ID")
    .clientKey("CLIENT_KEY")
    .server("wss://<your_subdomain>.back4app.io/").build()
);
// Init Live Query Client
ParseLiveQueryClient parseLiveQueryClient = null;
        
try {
    parseLiveQueryClient = ParseLiveQueryClient.Factory.getClient(new URI("wss://<your_subdomain>.back4app.io/"));
} catch (URISyntaxException e) {
    e.printStackTrace();
}

Then, you should create a ParseQuery for what type of object you want to subscribe. A subscription is an event emitter, which will fire events when changes happen to an object that satisfies your query. In this example, you will make a basic query and will subscribe all changes done to the Message objects that have the destination property set as pokelist.

See more about queries and subscriptions at Parse Official Queries Documentation.

querySubscribe.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Message - Live Query
if (parseLiveQueryClient != null) {
    ParseQuery<ParseObject> parseQuery = new ParseQuery("Message");
    parseQuery.whereEqualTo("destination", "pokelist");
    SubscriptionHandling<ParseObject> subscriptionHandling = parseLiveQueryClient.subscribe(parseQuery);

    subscriptionHandling.handleEvent(SubscriptionHandling.Event.CREATE, new SubscriptionHandling.HandleEventCallback<ParseObject>() {
        @Override
        public void onEvent(ParseQuery<ParseObject> query, final ParseObject object) {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                public void run() {
                    EditText pokeText = findViewById(R.id.pokeText);
                    numPokes++;
                    if(numPokes == 1) {
                        pokeText.setText("Poked " + numPokes + " time.");
                    }
                    else {
                        pokeText.setText("Poked " + numPokes + " times.");
                    }
                }
            });
        }
    });
}

Step 4 - Listen to other events

With creation events being listened on the application, now you can use other possibilities to code what your app will actually do when an event fires. In this part, we are going to show how to listen to these events in a practical example.

The Online Poke System example will serve as guidelines to your project, because there is little boilerplate here.

The main event that you are going to use is the create event. The complete list of events can be found here.

The createEvent is fired every time a ParseObject is created and fulfills the query constraints you’ve inserted. This event returns the created object.

In the Online Poke System example, the number of pokes is stored in the numPokes variable and new objects of our database will increase this variable when the create event fires.

Check out other existing options to manage Live Queries in your project:

createEvent.java

1
2
3
4
5
6
7
8
9
10
11
12
subscriptionHandling.handleEvent(SubscriptionHandling.Event.CREATE, new SubscriptionHandling.HandleEventCallback<ParseObject>() {
    @Override
    public void onEvent(ParseQuery<ParseObject> query, ParseObject object) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            public void run() {
                /* ... Code ... */
            }

        });
    }
});

updateEvent.java

1
2
3
4
5
6
7
8
9
10
11
12
subscriptionHandling.handleEvent(SubscriptionHandling.Event.UPDATE, new SubscriptionHandling.HandleEventCallback<ParseObject>() {
    @Override
    public void onEvent(ParseQuery<ParseObject> query, ParseObject object) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            public void run() {
                /* ... Code ... */
            }

        });
    }
});

deleteEvent.java

1
2
3
4
5
6
7
8
9
10
11
12
subscriptionHandling.handleEvent(SubscriptionHandling.Event.DELETE, new SubscriptionHandling.HandleEventCallback<ParseObject>() {
    @Override
    public void onEvent(ParseQuery<ParseObject> query, ParseObject object) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            public void run() {
                 /* ... Code ... */
            }

        });
    }
});

It’s done!

At this point, you have the knowledge in how to use Live Queries to make real-time reactive applications in an Android environment. You also know how to do the correct Live Query setup using Back4App and can start by implementing it in your own app.

You are now ready to explore Parse Server core features and Back4App add-ons.