0.2.5 • Published 4 months ago

react-native-mqtt-file-transfer v0.2.5

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

ReactNativeMqttFileTransfer

ReactNativeMqttFileTransfer is an Expo Module that enables efficient and flexible file transfer over MQTT in React Native (Expo) apps. It supports both JavaScript-side and native-side file chunking, allowing you to send arbitrarily large files in small increments. It also tracks transfer progress and MQTT connection state in real time, so your UI can remain responsive.

Table of Contents


Features

  • MQTT Connection Management: Connect to brokers supporting mqtt, mqtts, ws, or wss.
  • File Transfer: Send files with:
    1. Native chunking: the module itself splits the file.
    2. Sending a single chunk: your app iterates chunks and calls native once per chunk.
  • Progress Events: Real-time “onFileTransferProgress” with chunk index, total chunks, and percentage.
  • Connection Events: Real-time “onMqttStateChanged” (connected/disconnected).
  • Flexible Encoding: Out-of-the-box Base64 or UTF-8.
  • Test Message Publishing: Quickly verify MQTT connectivity via a small sample message.

Installation

  1. Install from npm (or your private registry):
    npm install react-native-mqtt-file-transfer
    # or 
    yarn add react-native-mqtt-file-transfer
  2. Prebuild / Rebuild if using managed Expo:
    npx expo prebuild
    or if using a bare React Native project, standard Gradle iOS/Android builds apply.

Configuration

Android

Some helpful tips on how to develop the Android part of this library:

  • In Android Studio, you want to open the example/android folder, not the android folder;
  • If there are Gradle errors, make sure that the Gradle JDK you selected is correct, e.g. Java 17 could be good. Change this in Android Studio -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle;
  • Remember that the logs are in the Logcat tab of Android Studio, not in the terminal;
  • If you want to debug the native code, add breakpoints in the code, start it using npx expo run:android, and then in Android Studio there is a button 'Attach debugger to Android process' (a green bug with a phone icon).

iOS

Some helpful tips on how to develop the iOS part of this library:

  • Xcode does not sync files changes such as creating or deleting files, from the file system automatically, so it's best to only make changes in Xcode and not another editor;
  • To open the project in iOS, run open ios/<MODULENAME>.xcworkspace in the example folder, then in Xcode navigate to Pods -> Development Pods -> -> Module.swift;
  • If you want to debug the native code, add breakpoints in the code, start it using npx expo run:ios, and then in Xcode click on Debug -> Attach to Process -> (likely targets);
  • You might need to run pod install in the ios folder;
  • If you want to test on a physical device, run npx expo run:ios --device and make sure that the device is connected with a cable. Also, you need to trust the developer on the device, go to General -> VPN & Device Management -> Developer App if you are prompted to trust the developer.

Usage

Import and Setup

import ReactNativeMqttFileTransfer from 'react-native-mqtt-file-transfer'; 

Initialize MQTT

await ReactNativeMqttFileTransfer.initializeMqtt(
  scheme,  // e.g. 'mqtt', 'mqtts', 'ws', 'wss'
  host,    // 'broker.emqx.io'
  port,    // e.g. 1883 for mqtt, 9001 for ws
  path     // optional, only needed if scheme is 'ws' or 'wss'; e.g. '/mqtt'
);
  • scheme: 'mqtt' | 'mqtts' | 'ws' | 'wss'
  • path: only required for WebSocket-based connections.

Sending Files

Key Parameters:

  • filePath: Local file path on the device (e.g., from DocumentPicker).
  • encoding: 'base64' or 'utf8' or 'none'.
  • destinationTopic: MQTT topic to publish to.
  • chunkSize: Byte size for splitting data (e.g., 64KB, 256KB).
  • chunkIndex (optional): If provided, only that chunk is sent; if omitted, the module automatically does native chunking.

Native Chunking

Let the native code handle reading and splitting your file. Omit chunkIndex:

await ReactNativeMqttFileTransfer.sendFile(
  filePath,
  'base64',
  'my/topic',
  64_000,       // chunkSize in bytes
  undefined,    // no chunkIndex => native chunking
);

JS Chunking

Split the file in JavaScript. For each chunk, pass the chunkIndex:

const totalChunks = Math.ceil(fileSize / chunkSizeInBytes);
for (let i = 0; i < totalChunks; i++) {
  await ReactNativeMqttFileTransfer.sendFile(
    filePath,
    'base64',
    'my/topic',
    chunkSizeInBytes,
    i
  );
}

Your app fully controls the iteration logic.

Publish a Test Message

await ReactNativeMqttFileTransfer.publishTestMessage('my/test');

Sends a small message ("Hello from Kotlin!" on Android or "Hello from Swift!" on iOS) to quickly confirm connectivity.


Listening for Events

Two main events: 1. onMqttStateChanged: - { connected: boolean } 2. onFileTransferProgress: - { chunkIndex: number, totalChunks: number, percentage: number }

Example using expo-modules-core EventEmitter:

import { EventEmitter } from 'expo-modules-core';
import ReactNativeMqttFileTransfer from 'react-native-mqtt-file-transfer';

useEffect(() => {
  const emitter = new EventEmitter(ReactNativeMqttFileTransfer);

  // Connection changes
  const connSub = emitter.addListener('onMqttStateChanged', (event) => {
    console.log('MQTT is now', event.connected ? 'connected' : 'disconnected');
  });

  // Transfer progress
  const progressSub = emitter.addListener('onFileTransferProgress', (progress) => {
    console.log(
      `Sending chunk ${progress.chunkIndex+1}/${progress.totalChunks} (${progress.percentage.toFixed(1)}%)`
    );
  });

  return () => {
    connSub.remove();
    progressSub.remove();
  };
}, []);

API Reference

1. initializeMqtt(scheme: string, host: string, port: number, path?: string)
Initializes the MQTT client.

  • scheme: 'mqtt' | 'mqtts' | 'ws' | 'wss'
  • host: e.g. 'broker.emqx.io'
  • port: e.g. 1883 for tcp, 8883 for ssl, 9001 for ws, 443 for wss
  • path: Optional string for WS subpath. If not provided for ws|wss, defaults to '/mqtt'.

2. sendFile(filePath: string, encoding: string, destinationTopic: string, chunkSize: number, chunkIndex?: number)
Sends a file or file chunk.

  • filePath: Local device path.
  • encoding: 'base64' | 'utf8' | 'none'
  • destinationTopic: MQTT topic.
  • chunkSize: Byte size for each chunk.
  • chunkIndex: If provided, only that chunk is read/sent; otherwise, the module streams the file.

3. publishTestMessage(topic: string)
Publishes a small test string to confirm connectivity.

4. Events

  • onMqttStateChanged{ connected: boolean }
  • onFileTransferProgress{ chunkIndex: number, totalChunks: number, percentage: number }

Memory/Performance Tips

  • Reduce Chunk Size if you see OutOfMemoryError.
  • Avoid Base64 if your broker and subscriber can handle raw binary ('none' or 'raw' encoding).
  • Use Native Chunking to avoid bridging large file data through JS.
  • If chunking in JS, add a brief delay (await new Promise(r => setTimeout(r, 50))) after each chunk to let GC catch up.

Contributing

  1. Fork this repository.
  2. Create a feature branch (git checkout -b feature/newFeature).
  3. Commit your changes.
  4. Open a pull request to discuss and merge your work.

We welcome bug reports, suggestions, and pull requests!


Testing with the example app

  1. On the root folder, run npm install && npm run build
  2. Go to the example folder, run npm install && npx expo run:ios or npm install && npx expo run:android

NPM

Repo in npm https://www.npmjs.com/package/react-native-mqtt-file-transfer Steps to publish to npm: 1. change version in package.json "version": "0.1.1" 2. npm login 3. npm publish

Full publish guide https://zellwk.com/blog/publish-to-npm/


License

ReactNativeMqttFileTransfer is released under the MIT License. See the LICENSE file for details.

0.2.1

5 months ago

0.2.0

5 months ago

0.2.3

4 months ago

0.2.2

5 months ago

0.2.5

4 months ago

0.2.4

4 months ago

0.1.1

2 years ago

0.1.0

2 years ago