首页 > 解决方案 > 未从 Firestore 获取数据

问题描述

我试图从 firestore 获取文档,它返回一个空数组但是当我运行 console.log(docs); 在声明的函数之外,它返回实际的数组。我知道会发生此错误,因为我的 useEffect 函数在从 firestore 获取文档之前首先运行。我想知道如何解决这个问题。

const Component = (props) => {
    const { docs } = useFirestore('books');
    const id = props.match.params.id;
    
    const loadContent = () => {
        const book = docs && docs.filter(doc => doc.id === id);
        console.log(book); //not getting book from the docs because docs is empty
    }
    
    useEffect(() => {
        async function getContent(){
            await loadContent();
        }
        getContent()
    },[]);
};

使用Firestore.js

import { useState, useEffect } from 'react';
import { firestore } from '../config/fbConfig';

const useFirestore = (collection) => {
    const [docs, setDocs] = useState([]);
    const [loading, setLoading] = useState(true);

    // getting realtime data from the firebase for books
    useEffect(() => {
        let unsubscribe = firestore.collection(collection)
        // .orderBy('createdAt', 'desc')
        .onSnapshot((querySnapshot) => {
          const items = [];
          querySnapshot.forEach((doc) => {
            items.push({...doc.data(), id: doc.id});
          });
          setDocs(items);
          setLoading(false);
        });
        return unsubscribe;
      }, []); // eslint-disable-line react-hooks/exhaustive-deps
  
    return { docs, loading };
}

export default useFirestore;

标签: javascriptreactjsfirebasegoogle-cloud-firestore

解决方案


我需要有关“useFirestore”代码的更多信息,但您至少应该这样编写代码。

  • 不要列出 Firestore 上的每个文档来只获取一个(您为每个读取请求付费)

  • 在 useEffect 中加载文档,而不是在外部

  • useEffect 必须依赖于 id

       const Component = (props) => {
           const id = props.match.params.id;
           const firestore = //;
           const [book, bookSet] = useState(false);
    
           useEffect(() => {
               //Depending on useFirestore code
               firestore.collections('books').doc(id)
               .then( snapshot => {
                   if ( !snapshot.exists ) {
                       bookSet(null);
                   } else {
                       bookSet(snapshot.data());
                   }
               });
           }, [id]);
    
           if( book === false) return <p>Loading</p>
           if (!book) return <p>Not exists</p>
           return <p>Display it</p>;
       };
    

这是我对你的“useFirestore”钩子的猜测

  const Component = (props) => {
      const id = props.match.params.id;
      const { docs, loading } = useFirestore('books');
      
      useEffect(() => {
          if( loading) console.log('Loading');
          return;

          const book = docs && docs.filter(doc => doc.id === id);
          console.log({book});
      },[loading, docs, id]);
  };

推荐阅读