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

Firebase(Swift):如何对比用户数组中的itemList匹配项

解决Firebase多用户物品匹配问题

嗨,我来帮你搞定这个多用户物品匹配的需求!先理清楚咱们的核心目标:找到所有和当前用户拥有至少一件相同物品的其他用户。结合你给出的数据结构,咱们一步步来解决:

先明确数据结构的小细节

你提供的itemList看起来像是JSON对象(键值对),而非数组——因为数组是按顺序索引的,而这里用物品ID(比如0、1、2)作为键,值为true表示拥有该物品。所以实际的itemList结构应该是这样的:

"itemList": {
  "2": true,
  "3": true,
  "0": true
}

这一点很关键,因为咱们要基于物品ID的键来做匹配。

核心实现步骤

1. 获取当前用户的物品集合

首先先拿到当前用户自己的itemList,把里面的物品ID提取出来存成一个集合(集合做交集判断效率更高):

guard let currentUserID = Auth.auth().currentUser?.uid else { return }

// 获取当前用户的itemList
Database.database().reference(withPath: "users/\(currentUserID)/itemList").observeSingleEvent(of: .value) { snapshot in
    guard let currentItemDict = snapshot.value as? [String: Bool] else { return }
    let currentUserItems = Set(currentItemDict.keys) // 转成集合方便后续对比
    
    // 下一步:获取所有用户并筛选匹配项
    self.fetchMatchingUsers(currentUserItems: currentUserItems, currentUserID: currentUserID)
}

2. 获取所有用户并筛选匹配项

接下来获取所有用户的数据,遍历每个用户,检查他们的itemList是否和当前用户的物品有交集:

func fetchMatchingUsers(currentUserItems: Set<String>, currentUserID: String) {
    let usersRef = Database.database().reference(withPath: "users")
    
    usersRef.observeSingleEvent(of: .value) { snapshot in
        var matchingUsers: [String: [String: Any]] = [:] // 存储匹配的用户数据
        
        for child in snapshot.children {
            guard let userSnapshot = child as? DataSnapshot,
                  let userData = userSnapshot.value as? [String: Any],
                  let userID = userSnapshot.key,
                  userID != currentUserID else { continue } // 跳过当前用户自己
            
            // 获取该用户的itemList
            guard let userItemDict = userData["itemList"] as? [String: Bool] else { continue }
            let userItems = Set(userItemDict.keys)
            
            // 检查是否有共同物品(交集不为空)
            if !currentUserItems.isDisjoint(with: userItems) {
                matchingUsers[userID] = userData // 把匹配的用户加入结果
            }
        }
        
        // 这里就是筛选后的匹配用户数组啦,可以做后续处理
        print("匹配的用户:", matchingUsers)
    }
}

针对你更新2.0的问题:如何筛选匹配键

上面的代码里,currentUserItems.isDisjoint(with: userItems) 这个方法就是判断两个集合是否没有交集——如果返回false,就说明有共同物品,这时候就把这个用户加入结果列表。这样就完成了筛选操作,解决了你说的“无法查询匹配的键”的问题。

性能优化建议(如果用户量较大)

如果你的用户数量很多,直接获取所有用户数据会比较慢,这时候可以做两个优化:

  • 反向索引:在Firebase里新建一个itemToUsers节点,结构是{物品ID: {用户ID: true}}。每当用户添加/删除物品时,同步更新这个节点。这样要找拥有某件物品的用户,直接查itemToUsers/物品ID就能拿到,再合并去重即可。
  • Cloud Functions:用云函数预先计算用户的匹配列表,定时或者在用户物品更新时自动更新,这样客户端直接读取预计算好的匹配结果就行,效率更高。

内容的提问来源于stack exchange,提问作者Chace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:25:54