【问题标题】:Unable to get 'where' clause working in a Firebase Query无法在 Firebase 查询中获取“where”子句
【发布时间】:2021-12-08 17:00:44
【问题描述】:

我无法让查询正常工作,这是我正在使用的钩子

export const useCollection = (collection, _query1, _orderBy  ) => {

const query1 = useRef(_query1).current;
const orderBy = useRef(_orderBy).current;

useEffect(() => {
  setIsPending(true);
  let ref = projectFirestore.collection(collection)


 if (query1) {
   ref = ref.where(query1)
}

 if (orderBy) {
   ref = ref.orderBy(orderBy);
 }

const unsubscribe = ref.onSnapshot(
  (snapshot) => {
    let results = [];
    snapshot.docs.forEach((doc) => {
      results.push({ ...doc.data(), id: doc.id });
    });

    // update state
    setDocuments(results);
    setError(null);
    setIsPending(false);
  },
  (error) => {
    console.log(error);
    setIsPending(false);
    setError("could not fetch the data");
  }
);

// unsubscribe on unmount
return () => unsubscribe();
}, [collection, query1, orderBy ]);

return { documents, error, isPending };
};

我在这个组件中使用了这个钩子

export default function ViewRxFigures() {
 const start =  new Date('2021-11-01')
 const { documents, error, isPending } = useCollection(
   "rxFigures",
   `'"dateForFigures", "<=" , "${start}"'`,
    "dateForFigures"
 );

得到一个

FirebaseError:使用无效数据调用函数 Query.where()。 不支持的字段值:未定义

它肯定与将查询的“where”部分传递到钩子中有关。当我使用这个将查询硬编码到钩子中时

const start = new Date("2021-11-01")

const ref = projectFirestore.collection(collection).where('dateForFigures', '<', start).orderBy('dateForFigures') 

查询工作正常并按预期返回数据。我花了很长时间尝试来自 SO 和互联网的不同解决方案,但不知道我应该如何通过日期。

firebase 中的“dateForFigures”存储为时间戳。

非常感谢您指出我哪里出错了,因为我没有找到对 SO 或其他地方有帮助的答案

【问题讨论】:

    标签: javascript reactjs firebase google-cloud-firestore


    【解决方案1】:

    我稍微简化了你的函数来测试它,这里的主要问题似乎是你将查询参数传递到你的钩子中的方式。当您执行查询时,它无法理解参数,因此会抛出您看到的错误。解决此问题的一种方法是将查询参数包含在数组中,并在使用它执行查询时将 deconstruct the array 括起来:

    
    function App() {
      const names = useCollection("users", ["userAge", ">", 23], "userAge"); // Query arguments are in an array
      console.log(names)
      return <div className="App"></div>;
    }
    
    export default App;
    
    

    这是完整的功能。它会在我的文档更改时获取所有名称属性:

    export const useCollection = (coll, queryArgs, ordering) => {
      
      const query1 = useRef(queryArgs).current;
      const orderBy = useRef(ordering).current;
      const [names, setNames] = useState([]);
    
      useEffect(() => {
        let ref = firestoreDB.collection(coll)
        if (query1) {
          ref = ref.where(...query1) //Query argument array is deconstructed here
        }
    
        if (orderBy) {
          ref = ref.orderBy(orderBy);
        }
    
        const unsubscribe = ref.onSnapshot(
          (snapshot) => {
            let newNames = [];
            snapshot.docChanges().forEach((change) => {
              newNames.push(change.doc.data().firstName);
            });
            setNames(newNames);
          },
          (error) => {
            console.log(error);
          }
        );
    
        // unsubscribe on unmount
        return () => unsubscribe();
      }, [coll, query1, orderBy]);
    
      return names;
    };
    

    另外需要注意的是,如果您只想处理文档更改,您还可以使用QuerySnapshot 中的docChanges() method。不过,这因每个用例而异。

    【讨论】:

    • 谢谢,我差点把它整理好,但就是想不通
    猜你喜欢
    • 2023-04-02
    • 2021-12-01
    • 2021-08-06
    • 2016-10-23
    相关资源
    最近更新 更多