Jeff spaulding
Jeff spaulding

Reputation: 31

Connecting to azure iot hub from client side react app within an iOS wrapper

We are attempting to connect a vite react web app to an azure iot hub.

We'd like to use a .pem, and .key file to register the device with gobal.azure-devices-provisioning.net as shown in their github repo example

https://github.com/Azure-Samples/azure-iot-samples-node/blob/5e06db800818cf5a4d0dcfeea19c749f62a3c2d7/provisioning/Samples/device/register_x509.js#L52

but the "azure-iot-provisioning-device-http", "azure-iot-security-x509", and"azure-iot-provisioning-device" rely on node packages that are not included in the device version, so having the web app do the registration/communication appears to be off the table.

Since the app is going to be running in a wrapper on a tablet we then tried both iOS and android SDKs and found similar missing packages in their versions. they don't seem to come with the capability to use the ProvisioningDeviceClient. I suspect that all of the microsoft sdk stuff is only intended for node.js or java servers, but they I didn't notice them specifying that anywhere in their docs

So with that set up, are we trying to do something super rare and weird? did I miss some important setup step? Any guidance, or tutorials for this would be amazing. Thank you all in advance.

in the react app we imported

    "azure-iot-device": "^1.18.3",
    "azure-iot-device-mqtt": "^1.16.3",
    "azure-iot-provisioning-device": "^1.9.1",
    "azure-iot-provisioning-device-mqtt": "^1.8.1",
    "azure-iot-security-x509": "^1.8.2",

but ran into those packages needing access to missing node.js packages like net and others to function. when i attempted the same thing in a simple node.js server app there was no problem and i was able to register with the server and connect.

in the iOS app we pod installed

  pod 'AzureIoTUtility', '=1.5.0'
  pod 'AzureIoTuMqtt', '=1.5.0'
  pod 'AzureIoTuAmqp', '=1.5.0'
  pod 'AzureIoTHubClient', '=1.5.0'

I went crawling around in their c code for a day and didn't find anything for registering the device

in the android app we added to the gradle.build

    implementation("com.microsoft.azure.sdk.iot:iot-device-client:1.30.1")
    implementation("com.microsoft.azure.sdk.iot:iot-service-client:1.30.1")
    implementation("com.microsoft.azure.sdk.iot:iot-device-client-provisioning:1.30.1")

but the com.microsoft.azure.sdk.iot.provisioning.device package doesn't exist so we can't get to the com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClient class

Upvotes: 1

Views: 200

Answers (1)

Sampath
Sampath

Reputation: 3639

Present there is only sdk support for node and node API. Provisioning classes issue with react+vite.

enter image description here

One best way is to use node api as backend and react +vite as front end where an Express server manages device registration using Azure IoT provisioning, while a React frontend allows users to trigger the registration process.

The below express backend code sets up an server to handle device registration requests using Azure IoT Provisioning Service.

  • It loads device certificates, configures the IoT Provisioning client, and exposes an endpoint /register for device registration
const express = require('express');
const fs = require('fs');
const Transport = require('azure-iot-provisioning-device-http').Http;
const X509Security = require('azure-iot-security-x509').X509Security;
const ProvisioningDeviceClient = require('azure-iot-provisioning-device').ProvisioningDeviceClient;
const cors = require('cors');

const app = express();

// Middleware to parse JSON bodies
app.use(express.json());

// Enable CORS
app.use(cors());

// Configuration
const provisioningHost = process.env.PROVISIONING_HOST;
const idScope =  process.env.PROVISIONING_IDSCOPE;
const registrationId = process.env.REGISTRATION_ID;

// Check if required environment variables are set
if (!idScope || !registrationId) {
  console.error('Please set ID_SCOPE and REGISTRATION_ID environment variables.');
  process.exit(-1);
}

// Device certificate and key paths
const deviceCertPath = 'C://device-cert.pem';
const deviceKeyPath = 'C://unencrypted-device-key.pem';

// Load device certificate and key
const deviceCert = {
  cert: fs.readFileSync(deviceCertPath).toString(),
  key: fs.readFileSync(deviceKeyPath).toString()
};

// Device provisioning client setup
const transport = new Transport();
const securityClient = new X509Security(registrationId, deviceCert);
const deviceClient = ProvisioningDeviceClient.create(provisioningHost, idScope, transport, securityClient);

// Device registration endpoint
app.post('/register', (req, res) => {
  // Register the device
  deviceClient.register((err, result) => {
    if (err) {
      console.error('Error registering device:', err);
      return res.status(500).json({ error: 'Device registration failed' });
    } else {
      console.log('Device registration succeeded');
      return res.status(200).json(result);
    }
  });
});

// Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});




enter image description here

The below react frontend provides a user interface for initiating device registration. When the user clicks the Register Device button, a POST request is sent to the backend’s /register endpoint.

import React, { useState } from 'react';

const App = () => {
  const [response, setResponse] = useState(null);
  const [error, setError] = useState(null);

  const registerDevice = async () => {
    try {
      const res = await fetch('http://localhost:3000/register', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      });

      if (!res.ok) {
        throw new Error(`Error: ${res.status} ${res.statusText}`);
      }

      const data = await res.json();
      setResponse(data);
      setError(null);
    } catch (err) {
      setResponse(null);
      setError(err.message);
    }
  };

  return (
    <div>
      <h1>Device Registration</h1>
      <button onClick={registerDevice}>Register Device</button>
      {error && <p style={{ color: 'red' }}>Error: {error}</p>}
      {response && (
        <pre>
          {JSON.stringify(response, null, 2)}
        </pre>
      )}
    </div>
  );
};

export default App;



enter image description here

  • To understand the details about the issue with React or React + Vite using Azure IoT Hub provisioning classes, please follow this issue.

  • Refer to this links for how to create React Native Wrappers for Native SDKs.

  • Refer to this link to provision an X.509 certificate simulated device with c code .

  • Refer this link to provision an X.509 certificate simulated device with java

<dependencies>
        <!-- Azure IoT Device SDK -->
        <dependency>
            <groupId>com.microsoft.azure.sdk.iot</groupId>
            <artifactId>iot-device-client</artifactId>
            <version>2.5.0</version>
        </dependency>
        
        <!-- Azure IoT Provisioning Device Client -->
        <dependency>
            <groupId>com.microsoft.azure.sdk.iot</groupId>
            <artifactId>provisioning-device-client</artifactId>
            <version>2.1.3</version>
        </dependency>
        .
        .
        .
  <dependencies>

Upvotes: 0

Related Questions