Firebase forEach获取数组后按serverTimestamp排序实现方案
代码修正方案
你的现有代码存在两处会导致功能异常的问题,需要同步修复:
- 异步时序问题:
forEach中传入async回调不会阻塞后续代码执行,排序逻辑运行时arrRef还未完成所有文档的写入,大概率是空数组 - 排序逻辑错误:Firebase 服务端时间戳拉取到客户端后是
Timestamp类型对象,包含seconds、nanoseconds两个属性,直接做减法运算会得到NaN,无法完成排序
修正后完整代码
将异步拉取逻辑改为Promise.all等待所有单文档请求完成后再执行排序,排序时调用Timestamp官方提供的toMillis()方法转为毫秒级时间戳做比较:
async letzteKontakteAbrufen(userid: string): Promise<LetzteKontakte[]> { const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats')); // 批量发起单文档拉取请求,等待所有请求返回 const contactPromises = docref.docs.map(async (docu) => { const docid = docu.data().id; const chatDocRef = doc(this.afStore, 'Chat', docid); const chatData = (await getDoc(chatDocRef)).data(); chatData.id = docid; return chatData; }); const arrRef = await Promise.all(contactPromises); // 按时间升序排序,更早的消息在前;需要最新消息在前就交换a、b位置 const sortMessages = arrRef.sort((a, b) => { // 兜底处理时间字段未同步为null的场景,避免报错 const timeA = a.time ? a.time.toMillis() : 0; const timeB = b.time ? b.time.toMillis() : 0; return timeA - timeB; }); return sortMessages; }
优化建议
如果后续聊天列表数据量较大,建议调整数据结构,将最后一条消息的时间戳冗余存储在chats子集合的文档中,直接在查询chats集合时使用orderBy('lastMessageTime')完成服务端排序,省去二次拉取全量聊天文档的开销,性能提升明显。
内容的提问来源于stack exchange,提问作者user19383419
相关产品推荐
相关产品推荐

