如何实现查询获取当前用户及关注用户的帖子?(Firebase+Swift)
解决方案
要实现Feed中同时显示当前用户和关注用户的帖子,你需要修改fetchFollowingPosts方法,将当前用户ID纳入查询范围,同时优化异步请求的处理逻辑(避免多次触发回调更新UI)。
修改后的FeedService代码
struct FeedService { // ... 保留原有uploadPost、fetchCurrentUsersPosts方法 ... func fetchFollowingPosts(forUid uid: String, completion: @escaping([Post]) -> Void) { var posts = [Post]() guard let currentUid = Auth.auth().currentUser?.uid else { return } let mainGroup = DispatchGroup() // 1. 获取当前用户自身的帖子 mainGroup.enter() fetchCurrentUsersPosts(forUid: currentUid) { userPosts in posts.append(contentsOf: userPosts) mainGroup.leave() } // 2. 获取所有关注用户的帖子 mainGroup.enter() COLLECTION_FOLLOWING.document(currentUid).collection("user-following") .getDocuments { snapshot, _ in guard let documents = snapshot?.documents else { mainGroup.leave() return } let followGroup = DispatchGroup() documents.forEach { doc in followGroup.enter() let followingId = doc.documentID COLLECTION_POSTS.whereField("uid", isEqualTo: followingId) .getDocuments { snapshot, _ in guard let docs = snapshot?.documents else { followGroup.leave() return } let followingPosts = docs.compactMap({ try? $0.data(as: Post.self) }) posts.append(contentsOf: followingPosts) followGroup.leave() } } followGroup.notify(queue: .main) { mainGroup.leave() } } // 3. 所有请求完成后统一排序并返回结果 mainGroup.notify(queue: .main) { let sortedPosts = posts.sorted(by: { $0.timestamp.dateValue() > $1.timestamp.dateValue() }) completion(sortedPosts) } } }
关键优化点
- 用
DispatchGroup管理所有异步请求,确保自身帖子和关注用户的帖子都获取完成后,再一次性回调更新UI,避免多次触发列表刷新 - 复用已实现的
fetchCurrentUsersPosts方法获取自身帖子,减少重复代码 - 对所有帖子统一按时间戳倒序排序,保证Feed的时序逻辑正确
可选优化:使用Firestore的in查询(适合关注人数≤10的场景)
如果你的用户关注人数通常不超过10人,可以用in查询减少请求次数,提升效率:
func fetchFollowingPosts(forUid uid: String, completion: @escaping([Post]) -> Void) { guard let currentUid = Auth.auth().currentUser?.uid else { return } COLLECTION_FOLLOWING.document(currentUid).collection("user-following") .getDocuments { snapshot, _ in guard let documents = snapshot?.documents else { completion([]) return } // 整理需要查询的UID集合:当前用户ID + 所有关注用户ID var targetUids = [currentUid] targetUids.append(contentsOf: documents.map({ $0.documentID })) // 用in查询一次性获取所有符合条件的帖子 COLLECTION_POSTS.whereField("uid", in: targetUids) .getDocuments { snapshot, _ in guard let docs = snapshot?.documents else { completion([]) return } let posts = docs.compactMap({ try? $0.data(as: Post.self) }) let sortedPosts = posts.sorted(by: { $0.timestamp.dateValue() > $1.timestamp.dateValue() }) completion(sortedPosts) } } }
注意事项
- Firestore的
in查询最多支持10个值,若关注人数超过10,需要拆分查询并合并结果 - 确保
Post模型的timestamp字段能正确解析为Date类型,否则排序逻辑会失效
内容的提问来源于stack exchange,提问作者amelia
相关产品推荐
相关产品推荐

