1

I'm trying to connect a web client to AWS IoT Core using JavaScript over WebSocket, authenticated via Amazon Cognito Identity Pool.

The connection works (confirmed via logs), and the subscription to the topic is successful, but I do not receive any messages, even though messages are actively published (verified using AWS Test Client).

I have granted permissions to the unauthenticated role used by Cognito and also attached the policy to the certificate used by the device.

IAM Policy used:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect",
        "iot:Subscribe",
        "iot:Receive",
        "iot:Publish"
      ],
      "Resource": "*"
    }
  ]
}

JavaScript code:

// --- Configuration ---
const AWS_REGION = '';
const COGNITO_IDENTITY_POOL_ID = '';
const IOT_CORE_ENDPOINT = '';
const MQTT_TOPIC = ''; 

// --- DOM Elements ---
const connectionStatusElement = document.getElementById('connection-status');
const iotDataElement = document.getElementById('iot-data');
const reconnectButton = document.getElementById('reconnect-button');

let connection; // Declare connection globally to manage its state

// --- Function to get AWS Credentials from Cognito ---
async function getAWSCredentials() {
    AWS.config.region = AWS_REGION;
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: COGNITO_IDENTITY_POOL_ID
    });

    try {
        await AWS.config.credentials.getPromise();
        console.log('Successfully got AWS credentials from Cognito.');
        return {
            accessKeyId: AWS.config.credentials.accessKeyId,
            secretAccessKey: AWS.config.credentials.secretAccessKey,
            sessionToken: AWS.config.credentials.sessionToken
        };
    } catch (error) {
        console.error('Error getting AWS credentials:', error);
        throw error; // Propagate the error
    }
}

// --- Function to Connect to AWS IoT Core and Subscribe ---
async function connectAndSubscribe() {
    connectionStatusElement.textContent = 'Connecting...';
    reconnectButton.style.display = 'none';

    try {
        const credentials = await getAWSCredentials();

        const clientID = `web_client_${Math.random().toString(16).substr(2, 8)}`; // Unique client ID

        // Initialize the AWS IoT MQTT Connection
        connection = new iot.AwsIotMqttConnection({
            endpoint: IOT_CORE_ENDPOINT,
            protocol: iot.AwsIotMqttConnectionConfig.ConnectThroughWebSocket,
            credentialsProvider: {
                get: {
                    credentials: () => ({
                        aws_access_key_id: credentials.accessKeyId,
                        aws_secret_access_key: credentials.secretAccessKey,
                        aws_session_token: credentials.sessionToken,
                    }),
                }
            },
            cleanSession: true,
            clientId: clientID,
            keepAlive: 30
        });

        // --- Event Listeners ---
        connection.on('connect', () => {
            console.log('Connected to AWS IoT Core!');
            connectionStatusElement.textContent = 'Connected';
            connectionStatusElement.style.color = 'green';

            // Subscribe to the topic
            connection.subscribe(MQTT_TOPIC, iot.QoS.AtLeastOnce)
                .then(() => {
                    console.log(`Subscribed to topic: ${MQTT_TOPIC}`);
                })
                .catch(error => {
                    console.error('Subscription error:', error);
                    connectionStatusElement.textContent = `Connected (Subscription Failed)`;
                    connectionStatusElement.style.color = 'orange';
                });
        });

        connection.on('message', (topic, payload) => {
            console.log(`Message received on topic ${topic}: ${payload.toString()}`);
            try {
                const data = JSON.parse(payload.toString());
                iotDataElement.textContent = JSON.stringify(data, null, 2);
            } catch (e) {
                iotDataElement.textContent = `Raw: ${payload.toString()}`;
                console.warn('Received non-JSON message:', payload.toString());
            }
        });

        connection.on('error', (error) => {
            console.error('MQTT Connection Error:', error);
            connectionStatusElement.textContent = `Error: ${error.message}`;
            connectionStatusElement.style.color = 'red';
            reconnectButton.style.display = 'block';
        });

        connection.on('close', () => {
            console.log('MQTT Connection Closed');
            connectionStatusElement.textContent = 'Disconnected';
            connectionStatusElement.style.color = 'gray';
            reconnectButton.style.display = 'block';
        });

        // --- Connect to IoT Core ---
        await connection.connect();

    } catch (error) {
        console.error('Failed to connect to AWS IoT Core:', error);
        connectionStatusElement.textContent = `Failed to Connect: ${error.message || error}`;
        connectionStatusElement.style.color = 'red';
        reconnectButton.style.display = 'block';
    }
}

// --- Reconnect Button Handler ---
reconnectButton.addEventListener('click', () => {
    if (connection && connection.isConnected) {
        console.log('Already connected, no need to reconnect.');
        return;
    }
    connectAndSubscribe();
});

// --- Initial Connection on Page Load ---
document.addEventListener('DOMContentLoaded', connectAndSubscribe);
1
  • The most common cause is topic mismatch. Make sure your AWS IoT Core topic is exact with your const MQTT_TOPIC Commented Jun 11 at 6:16

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.