React 应用程序中的 Firestore 客户端不使用 Websockets,而是发出数百个 POST 请求
P粉006847750
P粉006847750 2024-02-26 16:56:12
0
1
431

我是 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粉006847750
P粉006847750

全部回复(1)
P粉038856725

问题:

您每秒多次收到 post 请求的原因是因为您的 useEffect 没有任何依赖项数组并且

(突出显示的部分正在更改您的狗的状态,这会导致重新渲染,从而调用取消订阅方法,并且在重新渲染后再次输入 useEffect 并出现无限循环)

添加一个空数组应该可以解决该问题(是的,您应该担心并避免这种情况,因为它可能会导致前端和后端问题,例如性能、冻结、崩溃,并且还可能导致您需要支付一些 Firestore 账单)。 p>

如何修复它:

尝试将 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();
    },[]); // 

如果您正确设置其余部分,添加空依赖项数组(因此仅在组件安装时订阅)应该使您的数据保持同步(不需要 Firebase.INTERNAL.forceWebSockets(); 或类似的东西)

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!