如何在Firebase中对timestamp字段执行过滤查询并解决相关报错?
核心结论
合法的查询参数
针对Firebase Timestamp类型字段的比较查询,以下3种参数都可以正常使用:
Timestamp.now()(Timestamp对象)new Date()(Date对象)Date.now()(毫秒级时间数值)
仅Math.round(Date.now()/1000)(秒级时间数值)不可用:Firestore会把整数参数识别为毫秒级时间戳,传入秒级数值会被识别为1970年附近的时间,导致查询结果完全不符合预期。
无限重渲染问题的根因与解决方案
你遇到的Maximum update depth exceeded报错和参数类型无关,是query对象每次渲染都生成新引用导致的循环:
- 你的query构造逻辑写在组件根作用域,每次渲染都会重新调用
Timestamp.now()/new Date()/Date.now()生成全新的时间值 - 新的时间值会生成全新的query对象
useCollectionData检测到query依赖变化,重新执行查询并更新组件状态- 状态更新触发组件重新渲染,回到第一步形成死循环
修复方案
用useMemo缓存时间参数和query对象,保证渲染之间引用稳定:
import { useMemo } from 'react'; import { query, where, Timestamp } from 'firebase/firestore'; import { useCollectionData } from 'react-hooks-firebase'; // 组件内部 const YourComponent = () => { // 缓存组件挂载时的当前时间,依赖为空数组仅初始化一次 const currentTime = useMemo(() => Timestamp.now(), []); // 缓存query对象,仅当currentTime或ref变化时才重新构造 const q = useMemo(() => query(ref, where("next_spaced_revise", "<", currentTime)), [currentTime, ref] ); const [values, loading, error] = useCollectionData(q); // 剩余组件逻辑 // ... }
如果你的场景需要定时更新查询时间(比如每分钟刷新一次),可以用useState配合setInterval更新currentTime即可。
内容的提问来源于stack exchange,提问作者RetAFVLib
相关产品推荐
相关产品推荐

