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
相关产品推荐
相关产品推荐

