firebase / firebase/firebase-js-sdk

WebChannel Transport Error, Long Polling

Open
#7,354 12 comments 3 reactions 1 assignee Claimed by @wu-hui View on GitHub
api: firestore needs-attention question v9
Dominant language
TypeScript
Stars
5.1k
Forks
1k
Avg merge
2d 21h
Merged PRs (30d)
37

Description

### Operating System

Windows 11

### Browser Version

Chrome/111.0.5563.65

### Firebase SDK Version

9.17.1

### Firebase SDK Product:

Auth, Firestore, Functions

### Describe your project's tooling

React app with webpack

### Describe the problem

## I am often receiving a 400 error with a firestore listener in React JS, Tested on multiple browsers. ##

### Here is the error, stack trace minimally reduced: ###

```
GET https://firestore.googleapis.com/google.firestore.v1.Firestore/Listen/channel?gsessionid=[Truncated...] 400
k.send @ fetchxmlhttpfactory.js:270
k.da @ xhrio.js:664
ec @ channelrequest.js:570
Fd @ channelrequest.js:525
k.Ia @ webchannelbase.js:1673
xb @ run.js:140
Promise.then (async)
ub @ run.js:58
sb @ run.js:33
yc @ webchannelbase.js:1617
mc @ webchannelbase.js:2090
k.La @ channelrequest.js:619
k.ib @ channelrequest.js:596
kb @ eventtarget.js:351
C @ eventtarget.js:481
td @ xhrio.js:878
k.fb @ xhrio.js:866
k.Ha @ xhrio.js:842
hd @ fetchxmlhttpfactory.js:558
id @ fetchxmlhttpfactory.js:476
k.Ta @ fetchxmlhttpfactory.js:403
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Wa @ fetchxmlhttpfactory.js:355
Promise.then (async)
k.send @ fetchxmlhttpfactory.js:270
k.da @ xhrio.js:664
ec @ channelrequest.js:570
Fd @ channelrequest.js:525
k.Ia @ webchannelbase.js:1673
xb @ run.js:140
Promise.then (async)
ub @ run.js:58
sb @ run.js:33
yc @ webchannelbase.js:1617
mc @ webchannelbase.js:2090
k.La @ channelrequest.js:619
k.ib @ channelrequest.js:596
kb @ eventtarget.js:351
C @ eventtarget.js:481
td @ xhrio.js:878
k.fb @ xhrio.js:866
k.Ha @ xhrio.js:842
hd @ fetchxmlhttpfactory.js:558
id @ fetchxmlhttpfactory.js:476
k.Ta @ fetchxmlhttpfactory.js:403
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Wa @ fetchxmlhttpfactory.js:355
Promise.then (async)
k.send @ fetchxmlhttpfactory.js:270
k.da @ xhrio.js:664
ec @ channelrequest.js:570
Fd @ channelrequest.js:525
k.Ia @ webchannelbase.js:1673
xb @ run.js:140
Promise.then (async)
ub @ run.js:58
sb @ run.js:33
yc @ webchannelbase.js:1617
kc @ webchannelbase.js:2331
lc @ channelrequest.js:941
k.La @ channelrequest.js:619
k.ib @ channelrequest.js:596
kb @ eventtarget.js:351
C @ eventtarget.js:481
td @ xhrio.js:878
k.fb @ xhrio.js:866
k.Ha @ xhrio.js:842
hd @ fetchxmlhttpfactory.js:558
k.Ta @ fetchxmlhttpfactory.js:403
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Wa @ fetchxmlhttpfactory.js:355
Promise.then (async)
k.send @ fetchxmlhttpfactory.js:270
k.da @ xhrio.js:664
ec @ channelrequest.js:570
cc @ channelrequest.js:504
k.Ja @ webchannelbase.js:1331
xb @ run.js:140
Promise.then (async)
ub @ run.js:58
sb @ run.js:33
zc @ webchannelbase.js:1258
X.m @ webchannelbase.js:778
Hr @ index.esm2017.js:13053
send @ index.esm2017.js:12877
Bo @ index.esm2017.js:13392
zo @ index.esm2017.js:13554
xu @ index.esm2017.js:13905
(anonymous) @ index.esm2017.js:13940
$u @ index.esm2017.js:13939
(anonymous) @ index.esm2017.js:13472
(anonymous) @ index.esm2017.js:13500
(anonymous) @ index.esm2017.js:17414
(anonymous) @ index.esm2017.js:17447
Promise.then (async)
Hc @ index.esm2017.js:17447
enqueue @ index.esm2017.js:17414
enqueueAndForget @ index.esm2017.js:17392
(anonymous) @ index.esm2017.js:13500
(anonymous) @ index.esm2017.js:13472
so @ index.esm2017.js:12880
(anonymous) @ index.esm2017.js:13120
setTimeout (async)
wo @ index.esm2017.js:13115
jo @ index.esm2017.js:13518
Go @ index.esm2017.js:13471
(anonymous) @ index.esm2017.js:13461
Promise.then (async)
auth @ index.esm2017.js:13452
start @ index.esm2017.js:13357
(anonymous) @ index.esm2017.js:13482
(anonymous) @ index.esm2017.js:13258
(anonymous) @ index.esm2017.js:14306
(anonymous) @ index.esm2017.js:17414
(anonymous) @ index.esm2017.js:17447
Promise.then (async)
Hc @ index.esm2017.js:17447
enqueue @ index.esm2017.js:17414
enqueueAndForget @ index.esm2017.js:17392
handleDelayElapsed @ index.esm2017.js:14306
(anonymous) @ index.esm2017.js:14288
setTimeout (async)
start @ index.esm2017.js:14288
createAndSchedule @ index.esm2017.js:14282
enqueueAfterDelay @ index.esm2017.js:17487
Ro @ index.esm2017.js:13258
Oo @ index.esm2017.js:13481
start @ index.esm2017.js:13357
ku @ index.esm2017.js:13920
Bu @ index.esm2017.js:13947
close @ index.esm2017.js:13442
Qo @ index.esm2017.js:13491
(anonymous) @ index.esm2017.js:13475
(anonymous) @ index.esm2017.js:13500
(anonymous) @ index.esm2017.js:17414
(anonymous) @ index.esm2017.js:17447
Promise.then (async)
Hc @ index.esm2017.js:17447
enqueue @ index.esm2017.js:17414
enqueueAndForget @ index.esm2017.js:17392
(anonymous) @ index.esm2017.js:13500
(anonymous) @ index.esm2017.js:13475
io @ index.esm2017.js:12883
(anonymous) @ index.esm2017.js:13079
(anonymous) @ index.esm2017.js:13062
kb @ eventtarget.js:351
C @ eventtarget.js:481
Y.va @ webchannelbasetransport.js:428
R @ webchannelbase.js:2375
mc @ webchannelbase.js:2147
Q @ webchannelbase.js:522
k.La @ channelrequest.js:698
k.ib @ channelrequest.js:596
kb @ eventtarget.js:351
C @ eventtarget.js:481
td @ xhrio.js:878
k.fb @ xhrio.js:866
k.Ha @ xhrio.js:842
hd @ fetchxmlhttpfactory.js:558
k.Ta @ fetchxmlhttpfactory.js:403
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Wa @ fetchxmlhttpfactory.js:355
Promise.then (async)
k.send @ fetchxmlhttpfactory.js:270
k.da @ xhrio.js:664
ec @ channelrequest.js:570
Fd @ channelrequest.js:525
k.Ia @ webchannelbase.js:1673
xb @ run.js:140
Promise.then (async)
ub @ run.js:58
sb @ run.js:33
yc @ webchannelbase.js:1617
mc @ webchannelbase.js:2090
k.La @ channelrequest.js:619
k.ib @ channelrequest.js:596
kb @ eventtarget.js:351
C @ eventtarget.js:481
td @ xhrio.js:878
k.fb @ xhrio.js:866
k.Ha @ xhrio.js:842
hd @ fetchxmlhttpfactory.js:558
id @ fetchxmlhttpfactory.js:476
k.Ta @ fetchxmlhttpfactory.js:403
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Wa @ fetchxmlhttpfactory.js:355
Promise.then (async)
k.send @ fetchxmlhttpfactory.js:270
k.da @ xhrio.js:664
ec @ channelrequest.js:570
Fd @ channelrequest.js:525
k.Ia @ webchannelbase.js:1673
xb @ run.js:140
Promise.then (async)
ub @ run.js:58
sb @ run.js:33
yc @ webchannelbase.js:1617
mc @ webchannelbase.js:2090
k.La @ channelrequest.js:619
k.ib @ channelrequest.js:596
kb @ eventtarget.js:351
C @ eventtarget.js:481
td @ xhrio.js:878
k.fb @ xhrio.js:866
k.Ha @ xhrio.js:842
hd @ fetchxmlhttpfactory.js:558
id @ fetchxmlhttpfactory.js:476
k.Ta @ fetchxmlhttpfactory.js:403
Promise.then (async)
jd @ fetchxmlhttpfactory.js:370
k.Ta @ fetchxmlhttpfactory.js:228
Promise.then (async)
etc...
```
### React Devtools Warning ###
```
@firebase/firestore: Firestore (9.17.1): Connection WebChannel transport errored:
Jd {type: 'c', target: X, g: X, defaultPrevented: false, status: 1}
defaultPrevented
:
false
g
:
X {s: false, o: undefined, i: Ua, P: X, I: null, …}
status
:
1
target
:
X {s: false, o: undefined, i: Ua, P: X, I: null, …}
type
:
"c"
[[Prototype]]
:
Wb
```

Using `setLogLevel('debug')` I have found the following error logs:
```
[2023-06-04T21:54:23.588Z] @firebase/firestore: Firestore (9.22.1): PersistentStream close with error: FirebaseError: [code=unavailable]: The operation could not be completed
logger.ts:115 [2023-06-04T21:54:23.591Z] @firebase/firestore: Firestore (9.22.1): WebChannelConnection Creating RPC 'Listen' stream 0x86195108: https://firestore.googleapis.com/google.firestore.v1.Firestore/Listen/channel {"httpSessionIdParam":"gsessionid","initMessageHeaders":{"X-Goog-Api-Client":"gl-js/ fire/9.22.1","Content-Type":"text/plain","X-Firebase-GMPID":"1:845193017408:web:d13f2eab4cf84fbe2e47a5","Authorization":"Bearer |OMITTED|"},"messageUrlParams":{"database":"projects/|OMITTED|/databases/(default)"},"sendRawJson":true,"supportsCrossDomainXhr":true,"internalChannelParams":{"forwardChannelRequestTimeoutMs":600000},"forceLongPolling":false,"detectBufferingProxy":true,"xmlHttpFactory":{"l":null,"j":false},"encodeInitMessageHeaders":true}
```

This looks like a timeout error, but I think I am correctly unsubscribing to the listener. This may be an issue with the `useCallback()` hook nature.

### Steps and code to reproduce issue

Here is how I am initializing Firestore:

```
import { initializeApp } from "firebase/app";
import { initializeFirestore } from "firebase/firestore";

const fK = process.env.REACT_APP_FK;
const fDom = process.env.REACT_APP_FDOM;
const pId = process.env.REACT_APP_FPID;
const fSB = process.env.REACT_APP_FSB;
const fMSID = process.env.REACT_APP_FMSID;
const fId = process.env.REACT_APP_FID;
const fMID = process.env.REACT_APP_FMID;

const firebaseConfig = {
apiKey: fK,
authDomain: fDom,
projectId: pId,
storageBucket: fSB,
messagingSenderId: fMSID,
appId: fId,
measurementId: fMID
};

export const app = initializeApp(firebaseConfig);
export const db = initializeFirestore(app, {
experimentalAutoDetectLongPolling: true,
});
```

I have also tried *experimentalForceLongPolling*, and disabling *useFetchStreams*. using `getFirestore()` to initialize firestore does not work either, I still get the same error.

### MRE ###
```
const fetchUserData = useCallback(() => {
if (!navigator.onLine) {
navigate("/");
return;
}
if (auth.currentUser) {
const docRef = doc(db, "users", auth.currentUser.uid);
const unsubscribe = onSnapshot(
docRef,
(docSnap) => {
if (docSnap.exists()) {
const userData = docSnap.data();
// Handle userData
}
},
(error) => {
handleLogout();
console.error("Error fetching user data:", error);
}
);

// Cleanup function to detach listener
return () => {
unsubscribe();
};
} else {
navigate("/");
}
}, [navigate, handleLogout]);

useEffect(() => {
try {
fetchUserData();
} catch (error) {
setInfo("User data not found");
console.error(error);
navigate("/");
}
}, [fetchUserData, navigate]);
```

I have a feeling that it may have to do with my `useEffect()` and `useCallback()` hooks, but I am uncertain. The user data is working fine, changes in the user document are seen from the app, but this error always occurs multiple times.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.