React Native中如何基于Firestore时间戳正确过滤数据?
问题描述
我正在开发一个基于React Native和Firestore数据库的项目,存储的文章带有时间戳,希望在获取数据时进行过滤。
当前获取数据的代码如下:
const getLoads = async (e) => { const today = getCurrentSeconds(); console.log(today); await getDocs(collection(db, 'load')) .then((QuerySnapshot) => { const newData = QuerySnapshot.docs .filter((item) => item.date >= today) .map((doc) => ({...doc.data(), id:doc.id })); setLoad(newData); console.log(load, newData); }); setIsLoading(false); }
getCurrentSeconds()返回毫秒级时间戳(如1684829176108),但Firestore中的时间戳格式为{seconds: 1684748618, nanoseconds: 863000000},仅秒数部分有效。两者单位不匹配导致比较失效,需要实现仅比较秒数部分的过滤逻辑。
当前使用的时间辅助函数:
/* * Returns todays date */ export const getCurrentDate=() => { var date = new Date().getDate(); var month = new Date().getMonth() + 1; var year = new Date().getFullYear(); return date + '/' + month; } export const getCurrentSeconds=() => { var now = Date.now(); return now; }
解决方案
核心是统一时间戳的单位,推荐优先在查询阶段过滤(减少客户端数据处理量),也可在客户端统一单位后过滤。
方法一:客户端过滤(统一为秒级比较)
- 修改
getCurrentSeconds(),将毫秒级时间戳转为秒级:
export const getCurrentSeconds=() => { var now = Date.now(); return Math.floor(now / 1000); // 毫秒转秒并取整 }
- 调整数据处理逻辑,先映射完整文档数据,再取Firestore时间戳的
seconds字段做比较:
const getLoads = async (e) => { const today = getCurrentSeconds(); console.log(today); try { const querySnapshot = await getDocs(collection(db, 'load')); const newData = querySnapshot.docs .map(doc => ({ ...doc.data(), id: doc.id })) // 先获取完整文档数据 .filter(item => item.date.seconds >= today); // 用Firestore时间戳的秒数比较 setLoad(newData); console.log(newData); } catch (error) { console.error('获取数据失败:', error); } setIsLoading(false); }
方法二:Firestore查询阶段过滤(性能更优)
直接在Firestore查询时完成过滤,避免客户端拉取无关数据:
// 先导入Firestore相关工具 import { Timestamp, query, where, getDocs, collection } from "firebase/firestore"; const getLoads = async (e) => { const todayInSeconds = Math.floor(Date.now() / 1000); // 构造符合Firestore格式的时间戳对象 const todayTimestamp = new Timestamp(todayInSeconds, 0); try { // 查询时直接筛选时间戳大于等于当前时间的文档 const querySnapshot = await getDocs( query(collection(db, 'load'), where('date', '>=', todayTimestamp)) ); const newData = querySnapshot.docs.map(doc => ({ ...doc.data(), id: doc.id })); setLoad(newData); console.log(newData); } catch (error) { console.error('获取数据失败:', error); } setIsLoading(false); }
内容的提问来源于stack exchange,提问作者Olle Strandberg
相关产品推荐
相关产品推荐

