我正在创建一个iOS应用,其中我的Firebase实时数据库中具有一组标准的用户数据。用户数据由名称,年龄等值组成。这是结构:
user
- userId1
- name : Bob
- age : 25
- userId2
- name : Rob
- age : 24
- userId3
- name : Dylan
- age : 13
我还有另一个名为“ connections”的数据,其结构如下:
connections
- userId1
- userId2 : 1
- userId3 : 1
让我们说当前的用户ID是userId1。现在,当我按下按钮时,我想获取userId1的所有连接数据,即userId2和userId3。这里的问题是,如何查看“用户”结构并获取与userId2和userId3有关的用户信息?
简单来说,如何根据另一个结构中的数据过滤结构中的数据?似乎无法在线找到正确的解决方案。
我只能提取所有数据。不知道如何过滤数据。
答案 0 :(得分:2)
首先,您不是在过滤数据,而是在联接数据。因此,拥有正确的心态是一个重要的起点。
假设您没有在每个请求中获取数千个(无论如何都不应该获取),答案是,这可能无关紧要。 RTDB使用websocket并保持对服务器开放的管道,因此单独或作为单个查询请求它们没有多大区别。实际上,这主要是关于字节数的,如果您一次性读取每条记录或所有记录,字节数不会改变。因此,只需根据需要提取每个用户。
大规模地,不要害怕复制少量数据以提高读取效率。如果您只需要用户名即可将它们直接复制到您要执行大规模读取的地方(成千上万或更多)的数据中,就可以了。
还有一个great series for Firestore也最适用于RTDB,这是NoSQL数据结构(特别是第3集和第4集)的重要入门书。
答案 1 :(得分:0)
初次入门时,Firebase可能会有些棘手,因此这里有一些代码以及来自Kato的正确答案。
从概念上讲,首先,您想知道此用户连接的uid。为此,由于我们知道此用户uid,因此我们可以像这样直接从连接节点读取连接数据。
func readConnections() {
let uid = "userId1"
let thisUsersConnections = self.ref.child("connections").child(uid)
thisUsersConnections.observeSingleEvent(of: .value, with: { snapshot in
let connections = snapshot.children.allObjects as! [DataSnapshot]
for connection in connections {
let connectionUid = connection.key
self.printConnectionInfo(forUserId: connectionUid)
}
})
}
填充的快照将包含userId1节点的所有子数据,
- userId2 : 1
- userId3 : 1
在这种情况下,我想按它们在Firebase中出现的顺序读取它们,以便我们获取快照中包含的数据并填充一个数组。
let connections = snapshot.children.allObjects as! [DataSnapshot]
请注意,connections数组中的元素本身就是DataSnapshots。
迭代该数组以获取每个对象(一个DataSnapshot),每个快照的.key是每个用户连接的uid。然后,将密钥传递给另一个函数(为清楚起见),该函数读取用户信息以获取传入的uid,并在控制台上打印名称和年龄。
func printConnectionInfo(forUserId: String) {
let usersRef = self.ref.child("users").child(forUserId)
usersRef.observeSingleEvent(of: .value, with: { snapshot in
let name = snapshot.childSnapshot(forPath: "name").value as! String
let age = snapshot.childSnapshot(forPath: "age").value as! Int
print(name, age)
})
}