首頁  >  問答  >  主體

React 應用程式中的 Firestore 用戶端不使用 Websockets,而是發出數百個 POST 請求

我是 React 和 Firestore 新手(版本 9)。

我按照教學建立了一個簡單的偵聽器來讀取和顯示集合。我希望 Firestore 預設開啟 Websocket 並透過它保持文件同步。 事實證明,它每秒向端點 發出多次POST 請求https://firestore.googleapis.com/google.firestore.v1.Firestore/Listen/channel?VER=8&database=...

我不在 VPN 中,我的防火牆也不應阻止 Websocket。

我應該擔心如此大量的請求嗎? 我可以以某種方式強制 FS 使用 Websockets 嗎?

我讀了 Firebase.INTERNAL.forceWebSockets(); 但似乎無法在 Typescript 中存取。

我的元件:

export default function App() {
    const dogsCol = collection(firestore, 'dogs');

    const [dogs, setDogs] = React.useState<Dog[]>([]);

    useEffect(() => {
        const unSubscribe = onSnapshot(dogsCol, dogsSnap => {
            const dogsArray = dogsSnap.docs.map(dogSnap => {
                const dog = dogSnap.data() as Dog;
                dog.id = dogSnap.id;
                return dog;
            });
            setDogs(dogsArray);
        });

        return () => unSubscribe();
    });

    return (
        <Container maxWidth="sm">
            <Box sx={{ my: 4 }}>
                {dogs.map(dog => <div key={dog.id}>{dog.name}</div>)}
            </Box>
        </Container>
    );
}

我的 Firestore 設定:

const firebaseConfig = {
    apiKey: "...",
    // etc
};
const app = initializeApp(firebaseConfig);


export const auth = getAuth(app);
export const firestore = getFirestore(app);

const provider = new GoogleAuthProvider();
provider.setCustomParameters({
  prompt: 'select_account'
});

export const signInWithGoogle = () => signInWithPopup(auth, provider)

#
P粉006847750P粉006847750208 天前429

全部回覆(1)我來回復

  • P粉038856725

    P粉0388567252024-02-27 15:32:05

    問題:

    您每秒多次收到 post 請求的原因是因為您的 useEffect 沒有任何依賴項數組並且

    (突出顯示的部分正在更改您的狗的狀態,這會導致重新渲染,從而調用取消訂閱方法,並且在重新渲染後再次輸入 useEffect 並出現無限循環)

    新增一個空數組應該可以解決該問題(是的,您應該擔心並避免這種情況,因為它可能會導致前端和後端問題,例如效能、凍結、崩潰,並且還可能導致您需要支付一些Firestore 帳單)。

    如何修復它:

    #嘗試將 useEffect 更改為

    useEffect(() => {
            const unSubscribe = onSnapshot(dogsCol, dogsSnap => {
                const dogsArray = dogsSnap.docs.map(dogSnap => {
                    const dog = dogSnap.data() as Dog;
                    dog.id = dogSnap.id;
                    return dog;
                });
                setDogs(dogsArray);
            });
    
            return () => unSubscribe();
        },[]); // <- this empty array will cause this to only execute the effect onMount

    如果您正確設定其餘部分,新增空白依賴項陣列(因此僅在元件安裝時訂閱)應該會使您的資料保持同步(不需要Firebase.INTERNAL.forceWebSockets(); 或類似的東西)

    回覆
    0
  • 取消回覆