NodeJS Firestore(19.17.1)WebChannel传输错误,长轮询

vyswwuz2  于 2023-06-05  发布在  Node.js
关注(0)|答案(1)|浏览(123)

我经常在React JS中使用firestore侦听器收到400错误

下面是我如何初始化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,
});

我还尝试了 experimentalForceLongPolling,并禁用了 useFetchStreams。使用getFirestore()初始化firestore也不起作用,我仍然得到相同的错误。

以下是错误,堆栈跟踪最小减少:

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警告

@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

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]);

我有一种感觉,它可能与我的useEffect()useCallback()挂钩有关,但我不确定。用户数据工作正常,用户文档中的更改可以从应用程序中看到,这个错误似乎是不必要的。

编辑:

使用setLogLevel('debug'),我发现了以下错误日志:

[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}

这看起来像是一个超时错误,但我认为我正确地取消了对侦听器的订阅。这可能是useCallback()钩子特性的问题。
有什么想法吗

vql8enpb

vql8enpb1#

我认为问题在于听众没有取消订阅
问题是useCallback是一种在重新呈现之间缓存函数的方法,因此它永远不会执行取消订阅,除非您在useEffect中调用它。现在的方法是fetchUserData函数返回一个函数,这样您就可以取消订阅侦听器。

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);
        }
      );
  
      // Returns the function to do the cleanup <---
      return () => {
        unsubscribe();
      };
    } else {
      navigate("/");
    }
  }, [navigate, handleLogout]);
  

  useEffect(() => {
    try {
      const cleanup = fetchUserData();
      return cleanup;
    } catch (error) {
      // PS: I don't think you will get to this code since you are dealing with promises 
      setInfo("User data not found");
      console.error(error);
      navigate("/");
    }
  }, [fetchUserData, navigate]);

相关问题