【问题标题】:How do I get all documents in a Cloud Firestore collection using Version 9 of the Modular Web SDK?如何使用 Modular Web SDK 版本 9 获取 Cloud Firestore 集合中的所有文档?
【发布时间】:2021-09-18 23:18:43
【问题描述】:

我正在尝试使用第 9 版 Web SDK 获取集合中的所有文档。但是我收到了这个错误:

“TypeError: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;

【问题讨论】:

    标签: reactjs firebase next.js


    【解决方案1】:

    querySnapshotQuerySnapshot 对象的实例,而不是 JavaScript 数组。这意味着它没有像map()some()includes() 这样的普通数组方法。但是,它确实有自己的 forEach() method 版本,可用于迭代快照中的条目。如果需要访问普通数组的方法,可以使用快照的docs 属性(内部调用forEach() 组装数组)。

    要正确获取数组中的文档,可选择提取每个返回文档的名字,您可以使用以下任何策略:

    • 选项 1: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:useStateuseEffect 仅用于每个用户的 firstName
    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 这样的可摇树实用程序库来处理中间状态。
    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>
    );
    

    【讨论】:

    • "您可以使用快照的docs 属性代替(内部调用forEach() 来组装一个数组)我不知道,所以去检查一下,你是对的:github.com/firebase/firebase-js-sdk/blob/master/packages/… ? :)
    • @FrankvanPuffelen 是的,这是一个巧妙的小技巧,他们可以维护查询定义的顺序并提供基于数组的接口,而无需将数组原型注入到快照类中。
    • 我一直想在实时数据库的DataSnapshot 中添加map 和其他列表理解操作,但是……时间。 :-/
    • @samthecodingma 非常感谢您的快速回复。我很感激。
    猜你喜欢
    • 2021-11-19
    • 2021-03-27
    • 2021-05-09
    • 2021-11-16
    • 2018-03-15
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多