Building chat apps with QuickBlox React Native SDK

Posted on by Elena Kvitkovska

Using React Native framework, you can build cross-platform apps and save your money. It allows you to create real native apps using JavaScript and React. React Native has built-in components which compile to native UI ones. At the same time, your JavaScript code is executed through a virtual machine.

In this article, you will learn how to create a messaging app with QuickBlox React Native SDK.

Required For Setup

Building any application with QuickBlox SDK starts from creating QuickBlox application. To create an application you will need an account – you can register at https://admin.quickblox.com/signup or login if you already have an account. Then create your QuickBlox app and get app credentials. You will need them to identify your app.

All users of your QuickBlox message app can communicate by text or video chat. The app sill run across all platforms – iOS, Android, Web, etc.

Set Up

Creating React Native application starts from creating a new project:

react-native init AwesomeChatApp

To manage the application state we will use redux (with react-redux – react bindings for redux). To keep application state persistent after reloads / restart we will use redux-persist. And to make it work we should specify which storage engine we want to use, we will need async-storage also. And of course navigation – we will use quite popular and easy library react-navigation. Navigation library comes with a set of its dependencies, so we will need to install these as well:

react-native-reanimated
react-native-gesture-handler
react-native-screens

To install Quickblox React Native SDK you should run npm install
quickblox-react-native-sdk --save.

To install iOS dependencies we should enter ios folder (in terminal) and run

pod install

.

Once you have QuickBlox application credentials (Application ID, Authorization key, Authorization secret, and Account key) you can initialize QuickBlox React Native SDK:

const appSettings = {
  appId: '',
  authKey: '',
  authSecret: '',
  accountKey: '',
  apiEndpoint: '', // optional
  chatEndpoint: '' // optional
};

QB.settings
  .init(appSettings)
  .then(function () {
    // SDK initialized successfully
  })
  .catch(function (e) {
    // Some error occured, look at the exception message for more details
  });

If SDK initialized – it is ready to work. In order to perform some operations using QuickBlox SDK we should be signed in. To sign in we should run:

QB.auth
  .login({
    login: 'yourlogin',
    password: 'yourpassword'
  })
  .then(function (info) {
    // signed in successfully, handle info as necessary
    // info.user - user information
    // info.session - current session
  })
  .catch(function (e) {
    // handle error
  });

Now we are able to get dialogs, users, etc. But in order to send and receive messages in real-time, we should be connected over XMPP. To connect to chat call:

QB.chat
  .connect({
    userId: 12345,
    password: 'passw0rd!'
  })
  .then(function () {
    // connected successfully
  })
  .catch(function (e) {
    // some error occurred
  });

So now we are ready to chat.

Ready to Send your First Message?

You can make sure if you are connected to chat at any moment by calling:

QB.chat
  .isConnected()
  .then(isConnected => {
    // isConnected - boolean value
    // true - connected to chat
    // false - not connected
  })
  .catch(e => {
    // some error occured
  })

But in order to receive notifications about new messages we should instruct SDK to notify us about new messages and assign an event handler to process events accordingly. SDK contains several modules and some of them can emit events.

TIP: You can check if module can emit events – it should contain property “EVENT_TYPE” with a list of the available events for this module.

To assign an event handler that will process new messages run this:

import { NativeEventEmitter } from 'react-native'
import QB from 'quickblox-react-native-sdk'

function connectionEventHandler(event) {
  const { type, payload } = event
  // handle as necessary
}

function receivedNewMessage(event) {
  const { type, payload } = event
  // event.type - name of the event
  // event.payload - event data. Received message in this case.
}

const emitter = new NativeEventEmitter(QB.chat)

const QBConnectionEvents = [
  QB.chat.EVENT_TYPE.CONNECTED,
  QB.chat.EVENT_TYPE.CONNECTION_CLOSED,
  QB.chat.EVENT_TYPE.CONNECTION_CLOSED_ON_ERROR,
  QB.chat.EVENT_TYPE.RECONNECTION_FAILED,
  QB.chat.EVENT_TYPE.RECONNECTION_SUCCESSFUL,
]

QBConnectionEvents.forEach(eventName => {
   emitter.addListener(eventName, connectionEventHandler)
})

emitter.addListener(QB.chat.EVENT_TYPE.RECEIVED_NEW_MESSAGE, receivedNewMessage)

Now we are able to process new messages received or connection changes.

In order to send messages we should specify where we want to send them, i.e. specify the dialog. But do we have some dialogs? Get dialogs available for your user:

QB.chat
  .getDialogs()
  .then(function (result) {
    // result.dialogs - array of dialogs found
    // result.skip - number of items skipped
    // result.limit - number of items returned per page
    // result.total - total amount of items
  })
  .catch(function (e) {
    // handle error
  });

Putting It All Together

Let’s imagine there are no dialogs returned for our user. So we should create a new one to start messaging. In order to create dialog we should specify dialog participants.

Let’s get users to find someone to chat with:

const sort = {
  ascending: false,
  field: QB.users.USERS_FILTER.FIELD.UPDATED_AT,
  type: QB.users.USERS_FILTER.TYPE.DATE
}

QB.users
  .getUsers({ sort })
  .then(function (result) {
    // result.users - array of users found
    // result.page - page of results
    // result.perPage - how much items returned per page
    // result.total - total amount of items
  })
  .catch(function (e) {
    // handle error
  });

Now we can pick a user from results and create a new chat

QB.chat
  .createDialog({
    type: QB.chat.DIALOG_TYPE.CHAT,
    occupantsIds: [12345] // user.id
  })
  .then(function (dialog) {
    // handle as necessary, i.e.
    // subscribe to chat events, typing events, etc.
  })
  .catch(function (e) {
    // handle error
  });

If nothing goes wrong we will receive created dialog in the “resolve” block.

NOTE: Your chat opponent will not know that you have created a new chat with him. You should let him know somehow. This is where system messages can help.

In order to receive notifications from SDK about new messages in real-time we should say that we want to be notified:

QB.chat.subscribeMessageEvents({ dialogId: dialog.id })

You can also subscribe to “typing” events and message status (“read”, “delivered”) events.

Now we can send a message in a created dialog. Let’s try it out:

const message = {
  dialogId: dialog.id,
  body: 'Hey there!',
  saveToHistory: true
};

QB.chat
  .sendMessage(message)
  .then(function () { /* sent successfully */ })
  .catch(function (e) { /* handle error */ })

If promise resolved – the message sent successfully and you can expect that opponent will receive your message and send you a response. When there will be a new message in this dialog you will receive a notification.

Wrapping Up

Customer engagement and experience are essential to a company’s success. Chat app allows boosting user engagement and deliver useful solutions to your clients. Building your messaging app will give you the opportunity to start ahead of other competitors. This article shows how to simply create a chat app using QuickBlox React Native SDK.

For further reading on QuickBlox React Native SDK take a look at the official documentation.

Do you need any help? Don’t hesitate to contact us right now! Our sales team will be able to help you. Follow our new blog posts.