簡體   English   中英

如何使用模塊 Web SDK 的版本 9 獲取 Cloud Firestore 集合中的所有文檔?

[英]How do I get all documents in a Cloud Firestore collection using Version 9 of the Modular Web SDK?

我正在嘗試使用 Web SDK 的版本 9 獲取集合中的所有文檔。但我收到此錯誤:

“類型錯誤:querySnapshot.map 不是函數”

這是我收到錯誤的組件:

import { useEffect, useState } from "react";
import { collection, getDocs } from "firebase/firestore";
import { db } from "../../firebase";
function CurrentUser() {
  const [names, setNames] = useState([]);
  async function getMakers() {
    const querySnapshot = await getDocs(collection(db, "users"));
    querySnapshot.map((doc) => {
      setNames((doc.id = doc.data()));
    });
  }
  getMakers();
  return <div>{names.map((doc) => doc.firstName)}</div>;
}
export default CurrentUser;

querySnapshotQuerySnapshot object 的實例,而不是 JavaScript 數組。 這意味着它沒有普通的 Array 方法,如map()some()includes() 但是,它確實有自己的forEach()方法版本,可用於迭代快照中的條目。 如果您需要訪問普通數組的方法,則可以改用快照的docs屬性(它在內部調用forEach()來組裝一個數組)。

要正確獲取數組中的文檔,可選擇提取每個返回文檔的名字,您可以使用以下任何策略:

  • 方案一: useStateuseEffect對每個用戶的完整數據
import { useEffect, useState } from "react";

// ...

const [userDataArray, setUserDataArray] = useState([]);

useEffect(() => {
  let unsubscribed = false;

  getDocs(collection(db, "users"))
    .then((querySnapshot) => {
      if (unsubscribed) return; // unsubscribed? do nothing.
      
      const newUserDataArray = querySnapshot.docs
        .map((doc) => ({ ...doc.data(), id: doc.id }));

      setUserDataArray(newUserDataArray);
    })
    .catch((err) => {
      if (unsubscribed) return; // unsubscribed? do nothing.

      // TODO: Handle errors
      console.error("Failed to retrieve data", err);
    });

  return () => unsubscribed  = true;
}, []);

return (
  <div>
    { userDataArray.map((userData) => userData.firstName) }
  </div>
);
  • 選項 2:僅對每個用戶的firstName使用useStateuseEffect
import { useEffect, useState } from "react";

// ...

const [firstNamesArray, setFirstNamesArray] = useState([]);

useEffect(() => {
  let unsubscribed = false;

  getDocs(collection(db, "users"))
    .then((querySnapshot) => {
      if (unsubscribed) return; // unsubscribed? do nothing.
      
      const newFirstNamesArray = querySnapshot.docs
        .map((doc) => doc.get("firstName"));

      setFirstNamesArray(newFirstNamesArray);

      // need to remove duplicates? use this instead:
      // const firstNamesSet = new Set();
      // querySnapshot
      //   .forEach((doc) => firstNamesSet.add(doc.get("firstName")));
      // 
      // setFirstNamesArray([...firstNamesSet]);
    })
    .catch((err) => {
      if (unsubscribed) return; // unsubscribed? do nothing.

      // TODO: Handle errors
      console.error("Failed to retrieve data", err);
    });

  return () => unsubscribed  = true;
}, []);

return (
  <div>
    { firstNamesArray }
  </div>
);
  • 選項 3:使用像react-use這樣的 tree-shakeable 實用程序庫來處理中間狀態。
import { useAsync } from 'react-use';

// ...

const remoteUserData = useAsync(
  () => getDocs(collection(db, "users"))
);

if (remoteUserData.loading)
  return (<div>Loading...</div>);

if (remoteUserData.error) {
  console.error("Failed to load data! ", remoteUserData.error);
  return (<div class="error">Failed to load data!</div>);
}

const userDataArray = remoteUserData.value;

return (
  <div>
    { userDataArray.map((userData) => userData.firstName) }
  </div>
);

 useEffect(() => onSnapshot(collection(db, 'posts'), snapshot => { setPosts( snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })) ) }), [])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM