Changing state in React causes error 429 with Azure SignalR - reactjs

I am trying to make a React app with Azure SignalR, using this tutorial as a base. I haven't changed anything about the SignalR server, which can be found here. I'm using the JS version. The app works fine otherwise, but whenever the state changes, requests are sent to SignalR or something along those lines, eventually causing a 429 error. This is the output when state changes once:
[2020-01-09T15:11:42.207Z] Information: Normalizing '/api' to 'http://localhost:3000/api'.
[2020-01-09T15:11:42.437Z] Information: WebSocket connected to wss://bpm-drawing.service.signalr.net/client/?hub=chat&id=5_gylFnC52hduxXnoFT7dgb3b5d12b1&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1Nzg1ODI3MDIsImV4cCI6MTU3ODU4NDUwMiwiaWF0IjoxNTc4NTgyNzAyLCJhdWQiOiJodHRwczovL2JwbS1kcmF3aW5nLnNlcnZpY2Uuc2lnbmFsci5uZXQvY2xpZW50Lz9odWI9Y2hhdCJ9.byfLiITpaUPm9OLxjn-EN8XcwDT3_j6tdoN2uSdR91k.
[2020-01-09T15:11:42.440Z] Information: Using HubProtocol 'json'.
Enough consequent state changes cause a 429 error. Some of the error messages:
WebSocket connection to 'wss://bpm-drawing.service.signalr.net/client/?hub=chat&id=zer-1PBd58usOkZ2n-3Wuwb3b5d12b1&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1Nzg1ODI4OTYsImV4cCI6MTU3ODU4NDY5NiwiaWF0IjoxNTc4NTgyODk2LCJhdWQiOiJodHRwczovL2JwbS1kcmF3aW5nLnNlcnZpY2Uuc2lnbmFsci5uZXQvY2xpZW50Lz9odWI9Y2hhdCJ9.t7HPErziiAbQX1PLONvtF3tSHa4ezcBNgAhb0tgNJYA' failed: Error during WebSocket handshake: Unexpected response code: 429
[2020-01-09T15:14:59.060Z] Error: Failed to start the transport 'WebSockets': Error: There was an error with the transport.
POST https://bpm-drawing.service.signalr.net/client/negotiate?hub=chat&negotiateVersion=1 429
[2020-01-09T15:14:59.143Z] Error: Failed to complete negotiation with the server: Error
[2020-01-09T15:14:59.148Z] Error: Failed to start the connection: Error
Errors.ts:20 Uncaught (in promise) Error
at new HttpError (Errors.ts:20)
at XMLHttpRequest.xhr.onload (XhrHttpClient.ts:70)
I stripped my code down quite a bit but this is enough to cause the error:
import React from "react";
const signalR = require("#microsoft/signalr");
export const App = () => {
const [message, setMessage] = React.useState("");
const connection = new signalR.HubConnectionBuilder()
.withUrl(`/api`)
.configureLogging(signalR.LogLevel.Information)
.build();
connection.onclose(() => console.log("disconnected"));
connection.start();
function updateMsg(e) {
e.preventDefault();
setMessage(e.target.value);
}
return (
<div>
<form>
<input
type="text"
placeholder="Type message here..."
onChange={updateMsg}
/>
</form>
</div>
);
};
export default App;
The npm server just has a lot of
[HPM] POST /api/negotiate?negotiateVersion=1 -> http://localhost:7071

Okay so the problem is that the code inside App is run every time state updates, so the connection is formed again. Still haven't figured out quite how to solve it but at least I know what the cause is.
EDIT: Since I was asked, the solution is to put the forming of the connection inside a 'useEffect' hook, so that it's only run once, when the component is mounted.

Related

How to solve hydration errors related to dates in a React / Remix application?

I'm building an application as a hobby project and as an effort to try and learn server rendered React, but I've stumbled on a seemingly easy to fix error, but I do not know how I should approach the problem. Using Remix 1.10.
While my code runs, it is flawed. The server renders one thing and the client another, causing the rendered element to flicker on pageload. It also throws a multitude of errors in the console, like:
Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
24x react-dom.development.js:12507 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
react_devtools_backend.js:4012 Warning: Text content did not match. Server: "1/29/2023, 10:44:09 AM" Client: "1/29/2023, 12:44:09 PM"
The server is on UTC timezone but the client can be anything. In this case it's GMT+2. What should I do? I think I could set the server timezone to what the client timezone is but I also think that might be a terrible idea.
The best barebones dumbed down example I could make is this.
// routes/example.tsx
import { useLoaderData } from "#remix-run/react"
import {json, LoaderArgs } from "#remix-run/server-runtime"
export async function loader({ request }: LoaderArgs) {
const timestampFromDB = "2023-01-29T10:44:09.672Z"
return json({ time: timestampFromDB })
}
export default function HydrationError() {
const loaderData = useLoaderData<typeof loader>()
const time = new Date(loaderData.time)
const stamp = time.toLocaleString("en-US")
return (
<div>
Time:
<time>{stamp}</time>
</div>
)
}
I tried to look for answers before asking, but the closest thing I found isn't even close to what my problem is; Remix Hydration failed: UI on server and client do not match. In my case, it's not fine locally, it's not fine at all.
The toLocaleString spec allows output variations across implementations so you're probably better off avoiding the client's implementation and just using the server's implementation by moving toLocaleString to the loader.
// routes/example.tsx
import { useLoaderData } from "#remix-run/react"
import {json, LoaderArgs } from "#remix-run/server-runtime"
export async function loader({ request }: LoaderArgs) {
const timestampFromDB = "2023-01-29T10:44:09.672Z"
return json({ stamp: new Date(timestampFromDB).toLocaleString('en-US') })
}
export default function HydrationError() {
const { stamp } = useLoaderData<typeof loader>()
return (
<div>
Time:
<time>{stamp}</time>
</div>
)
}
Alternatively you might want to look at Intl.DateTimeFormat which gives you greater control over date rendering and may offer more consistency.
React Intl is a library built on top of Intl.DateTimeFormat which is worth checking out.

Next.js 13 - Fetch Failed Error. How do I resolve this?

I was trying the Next 13 beta version, and I faced a strange problem. What I am trying to do is, fetch data on the server side and display them on the page. However, the "fetch" operation fails on the server side. Below is the code for the Next.js page. It falls under the 'app' directory, as 'app/pageName/page.js'
import React from 'react'
async function callApi() {
const data = await fetch('https://marketplace-api.scistoneprojects.com/api/items/?search=yil');
return data.json();
}
export default async function Page() {
const data = await callApi();
return (
<main>
{data.results && data.results.map((product, index) => (
<h1>{product.title}</h1>
))}
</main>
)
}
Click to see Error Message. (UND_ERR_CONNECT_TIMEOUT)
Click to see API response (Django REST)
Click to see Next 13 Doc
Note: The fetch operation fails after ~ 10 seconds.
What I did:
I tried Axios, but it also fails.
I tried adding 'enableUndici: true' to the next config file. (Fails)
I tried other mock APIs, some work some don't. (Weird)
They all work normally on the client side.
They all work normally in the Next 12.
They all work normally on any other React app.
Versions:
node 18.12.0
next 13.1.0
react 18.2.0
react-dom 18.2.0
npm 9.2.0
Machine: Mac Mini M1 (Ventura 13.1)

React Axios requests are not possible when accessing React from another computer in the same network

I built a simple demo cinema management application with React.js and Flask.
The React movies component in which all the the cinema movies ( Fetched from Flask ) are displayed, works just fine - as long as I access the React url from the same computer (http://localhost:3000/movies ).
When I try to access React from another computer in my network, using the source computer IP which in my case is 10.0.0.14 ( http://10.0.0.14:3000/movies ), although React is working, I can't make axios API calls and I get the following error.
GET http://localhost:5000/movies net::ERR_CONNECTION_REFUSED
Uncaught (in promise) AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
xhr.js:220 GET http://localhost:5000/movies net::ERR_CONNECTION_REFUSED
Now, This is the part of my React code from which requests are made
useEffect(() =>
{
async function getMovies()
{
let resp = await axios.get("http://localhost:5000/movies/");
setMovies;
}
getMovies()
},[])
This is my Flask code:
from flask import Flask
import json
from bson import ObjectId
from flask_cors import CORS
from routers.persons import persons
class JSONEncoder(json.JSONEncoder):
def default(self, obj) :
if isinstance(obj, ObjectId):
return str(obj)
return json.JSONEncoder.default(self,obj)
app = Flask(__name__)
CORS(app)
app.url_map.strict_slashes = False
app.json_encoder = JSONEncoder
app.register_blueprint(persons, url_prefix="/movies/")
app.run()
Can somebody tell me how to fix this and allow axios requests when accessing React from another device?
Check your API call of the react app. You are using localhost even you are doing the api call from a different host browser. Change the localhost to the api host ip then it will work.
Change this to http://localhost:5000/movies/ to http://<api-ip-address>:5000/movies/.

Firebase production Error: ReferenceError: emptyChildrenSingleton is not defined

I have a nextjs project, v12.1.3 with react v18.1.0. I use firebase realtime database to handle notifications into my project. It works in develop mode, but it doesn't in production (on built environment).
The errors I get are the following:
ReferenceError: emptyChildrenSingleton is not defined
at new bV (a198fdd9-b0625f5d1b77c03a.js:1:75705)
at new cF (a198fdd9-b0625f5d1b77c03a.js:1:95593)
at a198fdd9-b0625f5d1b77c03a.js:1:124619
at get _repo [as _repo] (a198fdd9-b0625f5d1b77c03a.js:1:124994)
at get _root [as _root] (a198fdd9-b0625f5d1b77c03a.js:1:125199)
at d_ (a198fdd9-b0625f5d1b77c03a.js:1:120499)
at n (index-493c2cb0fc06fe87.js:1:879)
at index-493c2cb0fc06fe87.js:1:826
at g0 (framework-47484f2290a3befd.js:1:91915)
at h9 (framework-47484f2290a3befd.js:1:113308)
[2022-06-13T21:12:40.922Z] #firebase/database: FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot read properties of undefined (reading 'syncPointTree_')
at cM (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:99754)
at cI (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:97044)
at dC (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:109983)
at http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:124197
at ap (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:3775)
at d.onServerInfoUpdate_ (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:124182)
at d.handleTimestamp_ (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:43294)
at d.onReady_ (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:39829)
at aM.onConnectionEstablished_ (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:26211)
at aM.onHandshake_ (http://localhost:3000/_next/static/chunks/a198fdd9-b0625f5d1b77c03a.js:1:25266)
Uncaught TypeError: Cannot read properties of undefined (reading 'syncPointTree_')
at cM (a198fdd9-b0625f5d1b77c03a.js:1:99754)
at cI (a198fdd9-b0625f5d1b77c03a.js:1:97044)
at dC (a198fdd9-b0625f5d1b77c03a.js:1:109983)
at a198fdd9-b0625f5d1b77c03a.js:1:124197
at ap (a198fdd9-b0625f5d1b77c03a.js:1:3775)
at d.onServerInfoUpdate_ (a198fdd9-b0625f5d1b77c03a.js:1:124182)
at d.handleTimestamp_ (a198fdd9-b0625f5d1b77c03a.js:1:43294)
at d.onReady_ (a198fdd9-b0625f5d1b77c03a.js:1:39829)
at aM.onConnectionEstablished_ (a198fdd9-b0625f5d1b77c03a.js:1:26211)
at aM.onHandshake_ (a198fdd9-b0625f5d1b77c03a.js:1:25266)
The integration is very basic: I write my notification client side and create them server side with firebase-admin. So the problem is reading from realtime database (in prod only).
The code is something like this (i simplified it)
const [textData, setTextData] = useState<any[]>([]);
useEffect(() => {
initFirebase();
fetchData();
}, []);
const fetchData = () => {
const db = getDatabase();
const starCountRef = ref(db, 'testData');
onValue(starCountRef, (snapshot) => {
const data = snapshot.val();
setTextData(
Object.entries(data || {}).map(
([key, value]: [key: string, value: any]) => ({
key,
text: value?.text,
})
)
);
});
};
Where initFirebase() is a classic:
import { getApps, initializeApp } from 'firebase/app';
const firebaseConfig = {
//my configs
};
// Initialize Firebase
const initFirebase = () => {
if (getApps().length && getApps.length > 0) return getApps()[0];
return initializeApp(firebaseConfig);
};
export default initFirebase;
It might seem all right. And it is. I made this into an empty project and it actually work. (here the repo without the error).
I tried to replicate the error I have in my repo and I did it. This is the repo with the error. The error must be something with the packages, react or nextjs version, but I don't get it.
For simplicity You can take a look directly to the repos. I think the code is all right.
How do you think this error can be fixed?
P.S. the repos are also deployed on vercel, so you can try also to see the logs. Of course you can also make a PR.
I found out the problem is the last version of next (12.1.3).
In particular swcMinify. In fact, I had this option set to true into the file next.config.js. I also found out that there are several issues about swcMinify in production build. So, in order to solve the problem I described above, you just have to turn off swcMinify, or remove it. After that everything seems to be all right.
Conclusion: This is not a firebase error.

How to solve this error --> Error during the initialization of the SDK! DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope'

I am working on a React project, in that I am implementing Microblink https://www.npmjs.com/package/#microblink/blinkcard-in-browser-sdk npm for scanning credit cards but when I run the project it is showing this kind of error Error during the initialization of the SDK! DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope'
Please help to resolve this issue.
This is my code
import React from 'react';
import * as BlinkCardSDK from "#microblink/blinkcard-in-browser-sdk";
import './App.css';
const App = () => {
if (BlinkCardSDK.isBrowserSupported()) {
const loadSettings = new BlinkCardSDK.WasmSDKLoadSettings("sRwAAAYJbG9jYWxob3N0r/lOPmg/w35CpOHWK+o8YBgy/pGDcaB7TnbwT8mPpSzcCTWnV/AEyEIWVrcjyzdUSYb2bT0ccHxN4WDKrHoxoLQKBeq+ZukLOK13VwZXeikV4ggv2wrrW162/GIO5hajgqiEATKco+QfglS+OwguBweuacsuRR8UCD/YTdg4ysGMVljN7IIrthHPnmUa0SBOoeReXYvGmrKkVztIZzu9qkZoHu0UwCTN9Xloxa9Srw==");
BlinkCardSDK.loadWasmModule(loadSettings).then
(
(wasmSDK: BlinkCardSDK.WasmSDK) => {
},
(error: any) => {
// console.log('test')
console.log("Error during the initialization of the SDK!", error);
// console.log('testnew')
}
)
}
else {
console.log("This browser is not supported by the SDK!");
}
return (
<div>
</div>
)
}
export default App
If you have any questions please let me know.
Besides the license key, you also need to set the proper absolute path to the actual wasm and js support files of the SDK, a.k.a the engineLocation. The resource files need to be hosted somewhere accessible to the app.
There's a more detailed explanation of the SDK configuration in the documentation
Quick side note: it's probably not recommended to share your license key publicly, even if it's just a trial key.

Resources