Firestore按请求参数列表顺序获取文档列表的问题
解决Firestore书签列表与传入ID顺序不一致的问题
Firestore的whereIn查询不会保留传入ID数组的顺序,默认会按文档ID排序。要让返回的帖子与bookmarkList中的顺序一致,有两种可行方案:
方案一:客户端排序(推荐,简单高效)
拿到查询结果后,根据bookmarkList中的ID顺序重新排序结果列表。为了优化性能,建议先将bookmarkList转换为ID到索引的映射,避免多次调用indexOf带来的性能损耗。
修改后的代码示例:
await _firebaseFirestore .collection(_pathPosts) .where(FieldPath.documentId, whereIn: userProfileModel.bookmarkList) .withConverter( fromFirestore: PartiesPostModel.fromFirestore, toFirestore: (PartiesPostModel value, _) => value.toJson(), ) .get() .then( (QuerySnapshot<PartiesPostModel> querySnapshot) { logger.i("bookmark list successfully fetched"); List<PartiesPostModel> posts = querySnapshot.docs.map((doc) => doc.data()).toList(); // 提前构建ID到排序索引的映射,优化性能 final idToIndex = <String, int>{ for (int i = 0; i < userProfileModel.bookmarkList.length; i++) userProfileModel.bookmarkList[i]: i }; // 按照bookmarkList中的顺序排序 posts.sort((a, b) { // 确保不会出现null(如果查询结果中有不在bookmarkList的项,可根据需求处理) final indexA = idToIndex[a.postId] ?? int.maxValue; final indexB = idToIndex[b.postId] ?? int.maxValue; return indexA.compareTo(indexB); }); return posts; }, onError: (e) { logger.e("Error completing: $e"); return List.empty(); } );
方案二:调整数据结构,维护排序字段
如果需要服务端直接返回已排序的结果,可以修改用户文档的书签存储方式,为每个书签项添加排序优先级(比如时间戳或递增序号):
修改后的用户文档结构:
/user_id_a - user_id_a - user_name_aa - bookmarks: { "post_id_c": 1690000000000, // 添加书签的时间戳 "post_id_d": 1690000100000 }
实现步骤:
- 添加书签时,将postID作为键,当前时间戳作为值存入
bookmarks字段 - 获取书签列表时,先读取
bookmarks字段,将其转换为包含postID和排序值的列表并按排序值排序 - 再用排序后的postID数组调用
whereIn查询帖子
这种方式适合需要在多个客户端保持一致排序规则的场景,但需要额外维护排序字段。
内容的提问来源于stack exchange,提问作者foseja
相关产品推荐
相关产品推荐

