I am using Amplify-js in a static webApp. The app renders a satellite raster-map, retrieves a tracker history (geo) and subscribes to a topic on AWS IOT Core using using a pre-configured and working backend on AWS. It places a "live" tracker icon on a layer on the map updating the tracker position via a subscribes to an AWS IOT core topic.
Amplify.addPluggable(new AWSIoTProvider)
This all works correctly when run locally (npm start) but a production build (npm run build) results in:
TypeError: Cannot read properties of null (reading 'subscribe') at index.971eb3bc.js:870:34691 at tg (index.971eb3bc.js:32:24462) at dc (index.971eb3bc.js:32:42826) at index.971eb3bc.js:32:41074 at ze (index.971eb3bc.js:17:1673) at MessagePort.O (index.971eb3bc.js:17:2059)
Upon inspection of the Amplify object in the debugger, I see that the many fields are null in the production case and are non-null in the working case.
I've turned on verbose Amplify logger output and see a rather different log output when in the working vs non-working cases, but don't understand (and can't seem to find answers to) how the individual members of the Amplify object are actually populated and it seems there is a fair amount of magic happening even before the main.jsx ->amplify.configure() call as the PubSub field is already populated at that point (in the working case). The issue can be reproduced with just the PubSub portion of the app, which I've pasted below. I am happy to submit the simplified app if need be.
Expected behavior
I expect the same behavior from a production build and dev build or a clear indication of what to expect and ways to mitigate any issues that might ensue.
Reproduction steps
npm start
browse to localhost:8080
Observe working test app and normal log with no errors.
npm run build
npm run preview
browse to localhost:4173
observe white screen
open java console, observe:
TypeError: Cannot read properties of null (reading 'subscribe')
at index.f06f2e03.js:755:1349
at gl (index.f06f2e03.js:32:24445)
at Uo (index.f06f2e03.js:32:42757)
at index.f06f2e03.js:32:41021
at D (index.f06f2e03.js:17:1543)
at MessagePort.m (index.f06f2e03.js:17:1902)
Code Snippet
// Put your code below this line.
-------------- App.jsx ----------------
import React from 'react';
import './App.css';
import { useState, useEffect } from "react";
import { Amplify } from 'aws-amplify';
import { AWSIoTProvider } from '@aws-amplify/pubsub/lib/Providers';
import ReactLoading from 'react-loading';
import config from "../pubsub.json"
export default function App() {
const [gps1Data, setGps1Data] = useState({});
function ListGPSPos({posData}) {
if (Object.keys(posData).length === 0) {
return (
<ReactLoading type = "spinningBubbles" color ="#0"/>)
}
return (Object.keys(posData).map((key) => (
<li> {key}: {posData[key]} </li>
)
))
}
function decodeGPSData(input) {
switch (input.fPort)
{
case 2:
const obj = {};
obj.data = input.data;
obj.fPort = input.fPort;
setGps1Data(obj);
break;
default:
}
}
useEffect(() => {
Amplify.configure({
Auth: {
identityPoolId: config.REACT_APP_IDENTITY_POOL_ID,
region: config.REACT_APP_REGION,
userPoolId: config.REACT_APP_USER_POOL_ID,
userPoolWebClientId: config.REACT_APP_USER_POOL_WEB_CLIENT_ID
}
});
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: config.REACT_APP_REGION,
aws_pubsub_endpoint: `wss://${config.REACT_APP_MQTT_ID}/mqtt`,
}));
Amplify.PubSub.subscribe('application/Tracking/device/313932316e30740b/rx').subscribe({
next: data => decodeGPSData(data.value, data.fPort),
error: error => console.error(error),
close: () => console.log('Done'),
});
}, []);
return (
<>
<h1>AWS IOT Core test</h1>
<ListGPSPos posData = {gps1Data} />
</>
);
};