You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:01:16