Swift Firestore:如何筛选未被当前用户操作过的潜在匹配用户
解决方案
核心问题修正
你当前代码里的ref = db.collection("users").document(uid!)指向的是当前用户的单个文档,而非整个用户集合,后续的whereField查询逻辑完全不符合预期,这是首要修正点。另外,你需要先获取当前用户的blocked/liked/didntLike数组,再用这些ID过滤用户集合,避免重复查询已操作过的用户。
修正后的完整实现
func getPotentialMatches() { guard let currentUid = Auth.auth().currentUser?.uid else { print("用户未登录") return } let db = Firestore.firestore() // 先获取当前用户的已操作ID列表 db.collection("users").document(currentUid).getDocument { [weak self] userDoc, error in guard let self = self, let userDoc = userDoc, userDoc.exists else { print("获取当前用户信息失败: \(error?.localizedDescription ?? "未知错误")") return } // 合并三个数组的ID并去重 let blockedIds = userDoc["blocked"] as? [String] ?? [] let likedIds = userDoc["liked"] as? [String] ?? [] let didntLikeIds = userDoc["didntLike"] as? [String] ?? [] let excludedIds = Set(blockedIds + likedIds + didntLikeIds) excludedIds.insert(currentUid) // 加入自身ID,排除自己 // 构建查询 var query = db.collection("users") // Firestore的notIn最多支持50个元素,超过则先仅排除自身,后续客户端过滤 if excludedIds.count <= 50 { query = query.whereField("id", notIn: Array(excludedIds)) } else { query = query.whereField("id", isNotEqualTo: currentUid) } query.limit(to: 10).getDocuments { snap, error in if let error = error { print("查询潜在匹配用户失败: \(error.localizedDescription)") return } guard let documents = snap?.documents else { print("没有找到符合条件的用户") return } // 转换为User模型并添加到列表 self.potentialMatches.removeAll() for doc in documents { let userId = doc["id"] as? String ?? "" // 当excludedIds超过50时,客户端二次过滤 if excludedIds.count > 50 && excludedIds.contains(userId) { continue } // 假设你有User的初始化方法,比如init(from doc: DocumentSnapshot) if let user = User(from: doc) { self.potentialMatches.append(user) } } } } }
关键注意事项
- Firestore
notIn限制:Firestore的notIn操作最多支持50个值,若用户已操作ID总和超过50,需先仅排除自身,再在客户端遍历结果时过滤已操作ID。 - 安全解包:替换原代码中的强制解包
uid!,用guard let避免崩溃风险。 - 去重处理:用
Set合并三个数组的ID,避免重复排除同一用户。 - 模型转换:确保你的
User模型支持从DocumentSnapshot初始化,或根据字段手动解析数据。
内容的提问来源于stack exchange,提问作者OmniStack
相关产品推荐
相关产品推荐

