How to Build an Android Chat App with Kotlin using QuickBlox SDK
Kotlin is a relatively young language, but it is quickly gaining popularity among developers due to its convenience and modern approach to programming Android apps. Although it is still in development, Kotlin is already considered a mature ecosystem, offering important benefits in Android app development. In this article, we will work on everything you need for building an Android messenger app powered by QuickBlox.
To start off with the QuickBlox SDK, you need to go through a simple registration following this link
Creating a New Application in the Admin Panel
Now that you have an account with QuickBlox, you can proceed to the next preliminary step.
Create an application in the QuickBlox admin panel. QuickBlox application is a separate space to store your data, users, dialogs, future chat histories, custom objects, and more. To do this, simply click the “+” button.
Next step is to enter a brief description of the chat app:
As you can see on this screen, Title and Type are two required fields.
Title is the name of the application that will be displayed in the QuickBlox admin panel.
Type is the type of your application.
Please note that there can be more than one application inside your admin panel. It is recommended that you create a new QuickBlox application for every new project.
Click the “Add” button at the bottom of the page and the browser will redirect you to the screen with the application already created.
Accessing Credentials In the Admin Panel of the Application
At this point, we should see the following:
Next we will need the Application ID, Authorization key, Authorization secret, and below – the Account key. All these are required for the following authentication of the client-side application using QuickBlox API.
1. Connecting Quickblox Android SDK
To connect QuickBlox SDK to your app, import QuickBlox SDK dependencies via “build.gradle” file (Module: app):
The next step is to synchronize the project with Gradle files. To do this, click the appropriate button inside Android Studio – “Sync Project with Gradle Files”.
After successful synchronization of the project, the previously added dependencies will allow you to interact with the Quickblox Android SDK.
2. Quickblox Android SDK Initialization in the Application
First, we start by creating a new class which extends android.app.Application as follows:
Note that this class must be registered in AndroidManifest.xml. Specify the android:name property in the the node in AndroidManifest.xml:
Also, since we have just signed up, we do not have our own Chat and API servers (these are only available on the Enterprise plan), so there is no need to call the method
QBSettings.getInstance().zone = The Chat and API Domain values obtained will automatically be set.
We have created a library for this purpose, which contains claim type constants (
APPLICATION_ID, AUTH_KEY, ...) to use them both in the server and the client projects. Please note that these are your Application ID, Authorization key, Authorization secret and Account key “that you can find in the newly created application (step 0)”
Please be careful, while copying and pasting them into the value of the corresponding constants.
QBSettings.getInstance().init method must be called before we initialize Activities or Fragments. Which is why we had to create a class file that extends
After the initialization, a user authorization procedure can be performed.
Let’s say we have created a screen, which we correspondingly called
LoginActivity, where the application user can input, for example, username, password, and then click the “Login” button to enter the application:
To simplify* we apply user’s authorization with a username and password, but we can just enter an email + password.
*(Or even use the Firebase service for authorization and submit it to the server using the Firebase Project ID and Access Token.)
After the user inputs the username and password, we will need to build the
QBUser model for the following authorization and call the method of the QuickBlox Android SDK:
If you correctly added the dependencies to the build.gradle file (application level), all the resources from the QuickBlox Android SDK will be available, as well as the
QBUser model and the
QBUsers.signIn(...) method that we just used. If the model is not available, it means the dependencies are not connected correctly, or the project is not synchronized.
The code section above shows that when, as a result of the
QBUsers.signIn(...) method, the
onSuccess callback is invoked, this means that we are successfully logged in the API (as such“user existed”) and now we can log in to the Chat server.
In case something went wrong, the
onError callback will be invoked. Also, as it can be seen from the code section above – one of the reasons for this may be that this user has not yet been created and the API returns error 401.
Considering this we will create a new user using
After creating the user (Sign Up), we must log in with the newly created user by calling
signIn(...) method again.
To configure a connection to the Chat server is essential before connecting to it:
Now that we are successfully logged in, let’s proceed to authorization to the Chat server:
After successful authorization to the Chat server, we can interact with the API and Chat server.
4. Message List
Before sending messages, you need to download the already existing dialogs: in which our user is listed among occupants:
When dialogs are downloaded successfully, we have got the
ArrayList collection, which may be empty if the user doesn’t participate in at least one dialog.
You can save the downloaded dialog collection in any convenient and familiar way, and update as necessary. You will need it when a new dialog is created with the user, or the user was invited to an existing dialog.
It can be saved in an internal database, Shared Preferences, a class that exists while the application is running, or otherwise.
We can now create a dialog with any user that exists in the current QuickBlox application, but to do this you need to download at least several users first.
5. Getting Users from Dialogs
The first thing you can do next is to download and save users who already have dialogs. This must be done in order to get user models from the server and update information about them in our internal storage. Because, since the last update, someone could change their name, phone number, avatar, and other fields.
To download the models of specific users from the server, we can take the dialogs list, get participants from each dialog, create a list from the IDs of these users, and download them from the server. This can be done in the following way:
Here we have initiated a list of unique values from the user IDs that are occupants in each dialog available to us. Then we have created a
QBPagedRequestBuilder with the parameters
Per page = 100 and
page = 1.
Next, when calling the function
onSuccess callback (successful download), we check whether we have downloaded all the users, or if we repeat the request by increasing the “page number” by 1.
For example, if we have 146 unique users from the dialogs, our method will work twice. The first time it will load 100 users, then it will call itself again and load the remaining 46.
6. Getting Users by a Specific Parameter
Now let’s download more users from the server, for example, it will be the 100 recently created users from our QuickBlox application:
Please note that in order to create a dialog, you must have at least two users in your QuickBlox application. Users can be created in the admin panel, or by installing the application on several devices, after the registration of a new user (Sign Up).
QBUsers.getUsers(...) method is performed correctly, the onSuccess() callback will be invoked, which indicates the successful loading of the collection
ArrayList. Along with the Dialogs list, you can store it in any convenient and familiar way, and update as necessary.
7. Creating a Dialog
Now that we have some users, we can create a dialog with them.
Before we do this, let’s remember that there are three types of dialogs:
1. Private (
QBDialogType.PRIVATE) (when users communicate one-on-one and there is no way to add anyone else to this dialog).
2. Group (
QBDialogType.GROUP) (any number of users can participate in the dialog, usually 3 or more. We can also create a group dialog for two users, assuming that we want to add more participants to it).
3. Public (
QBDialogType.PUBLIC_GROUP) (All users from your application will be able to join it. The server will create a public chat and return a detailed information about the newly created dialog).
Important! The public dialog model does not contain a list of user IDs. Therefore, the value of
publicDialog.occupants an empty list.
Note. You can also create dialogs in the QuickBlox admin panel.
Let’s create a group dialog with any users from the list we have downloaded earlier:
At the beginning, we have created
usersIdsList: ArrayList. It is a collection of user IDs with whom we want to create a new dialog. We can create this list, for example, in the following way:
usersToCreateDialog is already the list of users with whom we want to create a dialog.
As a result, when
onSuccess() callback is triggered, we get the
QBChatDialog model of the dialog we just created. It can be added to those already stored, or again request the entire list of dialogs from the server, as we did earlier (
Note! After receiving a callback about the successful creation of the dialog (
onSuccess), we joined the dialog for sending and receiving messages using:
Now we are ready to send the first message to the new dialog.
8. Sending a message
Let’s compose a message and send it to the dialog:
Now, if we download the message history of this dialog, our message will appear in it.
9. Loading Chat History
To download the chat history, you should specify the chunk size of messages downloaded from the server (
limit), and the number of messages that should be skipped (
skip), in case we want the next chunk.
As a result of a successful request to the server,
onSuccess() callback works and we get a messages collection:
Just as in the case of downloading Dialogs and Users (
QBChatDialog, QBUser) – messages (
QBChatMessage) can be stored and updated in any way convenient for you.
Remember when we created the message, we set a parameter“
If the value of this parameter is false, then the message will not be saved on the server, and, accordingly, will not appear in the chat history downloaded from the server.
In the same way, we can load chat history from any dialog available to us.
10. Dialog Message Listener
Almost all the main functionality of our application is now described. Let’s see how to listen to the incoming messages.
All we need is to add a listener (
QBChatDialogMessageListener) to the Dialog or listen to all messages, not just from a specific one.
Let’s listen to only one dialog:
We can see, this listener has two callbacks:
processError. In this case, we need to process events from
processMessage. These events will be incoming messages, we will get a
QBChatMessage model including all the values of the model fields set by the sender.
– Let’s listen to all the dialogs:
We can use the same listener without a reference to a particular dialog. This is required when we need to receive incoming messages from all dialogs of the user.
11. Messages in the Background
Along with all the other functionality, we need to disconnect from the Chat server when the user sends the application to the background, by minimizing it, or by switching to another application.
As soon as we disconnect from the Chat server, the server understands that we have gone “offline”, and it is necessary to interact with the user in a different way.
Push notifications help to notify the user about any event, whether it is a new incoming message, a new dialog, a “friend” request, and so on.
The main advantage of Push notifications is that they will be received by the device even if our application is not currently running.
Push notifications are worth a separate article, so we’ll talk about them soon. For the scope of this tutorial the most important thing to know is that the Chat server, realizing that we are “offline”, for example, will monitor all messages in Private dialogs and as soon as we appear online (we launch the application, connect to the chat server and become “online” for it), the Chat server will consistently deliver to us messages that were addressed to us during our absence.
To disconnect from the chat server:
And to connect to the Chat server again, as I mentioned above, you need to call (
12. End a User Session – Logout
Now let’s say we need to sign in as another user, or just log out of the current user’s account in the application
As you can see, after a successful Logout from the API (QBUsers.signOut()), we need to log out from the Chat server, and at the same time clear everything that was connected with the current user session on the Chat server (QBChatService.getInstance().destroy()).
Now that we understand how it works, once again let’s go through the entire sequence of logic of the complete chat application, which you will be able to build by following the steps described in this article:
- Initialize the QuickBlox SDK
- Give the user a possibility to enter username and password (or email and password)
- Authorize the user in the API server (create a new one, or sign in as existing)
- Configure connection and authorization to the Chat server
- Initialize the listener for incoming messages
QBChatDialogMessageListenerin order to not miss messages.
- Download and save to temporary storage the dialogs in which this user participates.
- Collect user IDs from existing dialogs (if any) and load users that we “already know”.
- If you decide to create a dialog with users that are not yet among the already downloaded ones, load an additional 100 of the last created users, as an example.
- Create a new group dialog.
- Compose a message and send it to the previously created dialog.
- Download the chat history in this dialog, or in any other (if we have a screen displaying the chat history in the dialog, then we need to download the latest chat history every time a user wants to enter the dialog and view his history, or write a new message).
- Disconnect from the Chat server when minimizing the application (go to background), and connect to the Chat server when going to foreground.
More details about how to build a fully functional chat in-app using Kotlin application, how to handle various situations and user behavior in it, how to send and receive push notifications, how to attach photos, audio, video and other types of files to messages, how to use the status delivery of messages and notifications about what your opponent is currently writing to you, as well as much more you can find out by downloading our example from the QuickBlox repo on GitHub.
There are more features available to support more advanced use-cases such as push notifications, content moderation, rich messages, and more. Feel free to contact us if you have any questions.
Please check our official QuickBlox Android documentation for more information.