Mukesh Mandiwal JavaScript | React | React Native | TypeScript | GraphQL

Guide to building a React Native MQTT messaging app

5 min read 1404

React Logo Over Hypnotic Red Background

React Native is a JavaScript-based cross-platform mobile application development framework. React Native uses React to write mobile applications for the iOS and Android platforms and provides comparable performance and usability to that of native applications.

The Internet of Things (IoT) powers many mobile applications, and React Native assists in the development of IoT apps. The MQTT (Message Queuing Telemetry Transport) protocol facilitates communications between IoT devices and enables bidirectional data exchange between the client and the server.

In this article, we’ll demonstrate how to set up an MQTT broker to subscribe and publish topics to iOS and Android apps using a client broker. We’ll also show how to configure and connect MQTT to a React Native application.

Contents

What is MQTT?

MQTT is a common messaging protocol for the Internet of Things. This real-time messaging protocol (often referred to as a machine-to-machine protocol) is a device communication mechanism that is designed for fast data transmission.

MQTT is a lightweight publish and subscribe messaging transport that allows us to send and receive messages. It facilitates communication between several devices.

Setting up the React Native project

To follow along with this guide, ensure your development environment has the following configurations:

  • Node.js installed, v10 or higher
  • npm and Yarn package manager
  • react-native-cli

Check out React Native’s official documentation for detailed instructions on how to set up a React Native development environment on your local machine.

Use the below commands to create the React Native project:

npx react-native init recatNativeMqtt
# navigate to project directory
cd recatNativeMqtt

Adding the MQTT library

To connect our application to MQTT, we’ll use an open source library, Eclipse Paho JavaScript Client from the Eclipse Paho Project, to communicate with the MQTT broker. The Eclipse Paho Project aims to offer a messaging protocol solution that is effective, lightweight, and scalable.

There are many programming languages that support Eclipse Paho. We’re using the Eclipse Paho JavaScript client since our solution uses React Native, a JavaScript-based framework. The Paho JavaScript client is a browser-based MQTT solution and uses WebSockets to connect to an MQTT broker.

To add the Paho JavaScript client, create a lib folder at the root level of our project, create an mqtt.js file, and add the following source code to the file.

Next, we need to provide the Paho JavaScript client with access to the local storage. We create a storage.js file under the lib folder and add an in-memory alternative to global localStorage, like so:

const storage = {
  setItem: (key, item) => {
    storage[key] = item;
  },
  getItem: key => storage[key],
  removeItem: key => {
    delete storage[key];
  },
};
export default storage;

Now that we’ve added the MQTT library, we need to configure the MQTT broker; this intermediary will enable the clients to communicate.

Configuring the MQTT broker

There are several free MQTT brokers that may be selected. For this article, we’ll use the Eclipse Mosquitto MQTT broker, an open source message broker used for the MQTT protocol.

Detailed download and configuration information to set up Mosquitto for the development environment is available in the official docs. Configuration can also be handled using Eclipse Mosquitto Docker images, as described in Docker’s instructions.

The Paho JavaScript client requires either the usage of a gateway that can forward between WebSockets and TCP or a broker that natively supports WebSockets.

To enable WebSockets to listen on port 9001, we add the below code to the mosquitto.config file to access the config file; the path location is /usr/local/etc/mosquitto/mosquitto.conf:

listener 1883 0.0.0.0
allow_anonymous true


listener 9001 127.0.0.1
protocol websockets

Protocol Websockets

To start the Mosquitto broker on the development environment, run the below command:

/usr/local/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf

After this command is executed, the MQTT broker will be running on the localhost and will start listening on port 9001.

Next, run the following commands to launch the React Native application in the iOS simulator and the Android emulator:

# To start metro
yarn react-native start 

# TO start iOS simulator
yarn react-native run-ios

# To start Android emulator
yarn react-native run-android

As shown below, the iOS simulator is running and showing that it is connected to MQTT:

MQTT Connected to iOS

The Android emulator is also running and showing that it is connected to MQTT, as shown below:

MQTT Connected to Android

Configuring MQTTBox for testing

MQTTBox is a free and open source developer tool for monitoring and testing the MQTT server. We can use MQTTBox to subscribe the topic and publish the payload to subscribed devices. MQTTBox connects to MQTT brokers in order to send messages to our application.



We‘ll use MQTTBox chrome extensions to test our MQTT broker and publish messages.

The below MQTTBox screens show how to configure MQTTBox to localhost:

Configure MQTTBox to Localhost

Topic Boxes

As shown below, we are publishing to the same topic and subscribing to it from the MQTTBox to verify that our broker is up and running:

Publish and Subscribe Topics

Next, we’ll demonstrate how to publish the subject via MQTTBox and subscribe from a React Native app.

Publishing and subscribing with MQTT

The MQTT message publish-subscribe (or pub/sub) model is an alternative to the traditional client-server model for IoT-based implementations. A client may only publish a payload or message to a single topic; it cannot publish to several topics at once. But if the client or app is subscribed to the same topic, this could be received by numerous groups.

To implement MQTT pub/sub, we create an MqttClient service under the utils folder and assign the below connect configuration and onPublish and onSubscribe methods:

/* this.client = new Paho.MQTT.Client('host',PORT, clientId);
*/
this.client = new Paho.MQTT.Client('127.0.0.1', 9001, clientId);

In Android, 127.0.0.1 (localhost) will throw a Socket error. To avoid this error, use your system IP address for the host:

Socket Error

  onPublish = (topic, message) => {
    this.client.publish(topic, message);
  };
onSubscribe = (topic, callback) => {
    this.callbacks[topic] = callback;
    this.client.subscribe(topic);
  };

The flow of publishing MQTT messages or payloads is dependent on the Quality of Service (QoS), or the guarantee that the messages will be delivered correctly.

MQTT supports three QoS levels:

  • QoS-0: This default level does not ensure the delivery of publishing payloads
  • QoS-1 and QoS-2: These levels ensure that messages are sent even when a device is offline or not connected to MQTT

When the clean session flag is false, all messages will be held in a queue until they are sent to subscribed subjects and acknowledged back. Once it is reconnected to MQTT, the device will send all queued messages to subscribed topics.

In the below example, a topic fromClient is published from the MQTTBox with a payload message after it has been subscribed from the React Native app. The payload message is displayed in the iOS app:

Payload Message in iOS

Next, we publish a message from a React Native app using the fromRNAPP topic and subscribe to it using the MQTTBox. The payload message is in the MQTTBox, as shown below:

Payload Message in MQTTBox

Now, we publish and subscribe to the same topic in a React Native app, and as soon as it is published, we get the payload message and display it in the app:

Payload Message in App

Handling failed messages in React Native

If the React Native app disconnects from the MQTT broker, the published message will fail to deliver. In this scenario, the app will retry to connect to the broker to receive the queued message for the subscribed topic based on the keepaliveInterval.

If the app is not connected or not receiving a ping message from the broker, the keepaliveInterval will have a non-zero value. This will prompt the app to attempt to connect to the broker, as shown below:

onError = ({errorMessage}) => {
    this.isConnected = false;
    Alert.alert('Failed', 'Failed to connect to MQTT', [
      {
        text: 'Cancel',
        onPress: () => console.log('Cancel Pressed'),
        style: 'cancel',
      },
      {
        text: 'Try Again',
        onPress: () =>
          this.onConnect(this.onSuccessHandler, this.onConnectionLostHandler),
      },
    ]);
  };

Failed to Connect MQTT

Conclusion

In this article, we discussed the MQTT messaging protocol setup and configuration for development using the Eclipse Mosquitto MQTT broker.

We also developed a React Native MQTT app, using the Eclipse Paho JavaScript Client library, and used this app to demonstrate subscribing to topics, posting messages, and receiving messages from the server.


More great articles from LogRocket:


I hope you enjoyed this article. The source code for the React Native MQTT application used in this article is available on my GitHub.

LogRocket: Instantly recreate issues in your React Native apps.

LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.

LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.

Start proactively monitoring your React Native apps — .

Mukesh Mandiwal JavaScript | React | React Native | TypeScript | GraphQL

Leave a Reply