Ios 查询Firebase数据库中的多个密钥
我刚刚开始使用Firebase数据库,在高效查询数据方面遇到了一些麻烦。我当前的数据库结构类似于Firebase文档中推荐的数据结构,我们在其中看到以下示例:Ios 查询Firebase数据库中的多个密钥,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我刚刚开始使用Firebase数据库,在高效查询数据方面遇到了一些麻烦。我当前的数据库结构类似于Firebase文档中推荐的数据结构,我们在其中看到以下示例: // An index to track Ada's memberships { "users": { "alovelace": { "name": "Ada Lovelace", // Index Ada's groups in her profile "groups": {
// An index to track Ada's memberships
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
// Index Ada's groups in her profile
"groups": {
// the value here doesn't matter, just that the key exists
"techpioneers": true,
"womentechmakers": true
}
},
...
},
"groups": {
"techpioneers": {
"name": "Historical Tech Pioneers",
"members": {
"alovelace": true,
"ghopper": true,
"eclarke": true
}
},
...
}
}
我遇到的问题是,我不确定如何有效地检索特定用户的所有组名。我可以轻松检索用户的所有组ID:
usersRef.child("alovelace").child("groups").observeSingleEvent(of: .value, with: { (snapshot) in
// code to store group IDs
})
但是现在我能想到的获取所有组名的唯一方法是通过ID进行for循环,然后对每个组进行.observeSingleEvent调用以获取名称。但是,如果我有一个非常大的用户组集呢?理想情况下,我不希望进行太多的数据库调用,只需在一次调用中完成。使用此数据结构是否可行?您可以执行以下操作:
usersRef.child("alovelace").child("groups").observeSingleEvent(of: .value, with: { (snapshot) in
let result = snapshot.children.allObjects as? [FIRDataSnapshot]
for child in result {
let groupName = child.key
print(groupName)
}
})
这就是我建议你做的。这将使用用户所属的组树中的所有数据填充组数组
import UIKit
import Firebase
class TableViewController: UITableViewController {
var groups = Array<Group>()
override func viewDidLoad() {
super.viewDidLoad()
Group.get(userUID: "alovelace") { (groups) in
for uid in groups {
Group.get(groupUID: uid, completion: { (group) in
if let group = group {
print(group)
self.groups.append(group)
} else {
print("There is no group with id: \(uid)")
}
self.tableView.reloadData()
})
}
}
}
}
struct Group {
var uid: String
var name: String
var members: Array<String>
init?(uid:String, dict:Dictionary<String,Any>){
guard
let name = dict["name"] as? String,
let users = dict["members"] as? Dictionary<String,Bool>
else {
return nil
}
self.uid = uid
self.name = name
self.members = Array<String>()
for (id, _) in users {
self.members.append(id)
}
}
// Returns a Group, when given a group id.
static func get(groupUID:String, completion: @escaping (Group?) -> ()) {
let ref = FIRDatabase.database().reference().child("groups").child(groupUID)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if let value = snapshot.value as? Dictionary<String,Any> {
if let group = Group(uid: groupUID, dict: value) {
completion(group)
return
} else {
print("Incomplete Group Data")
}
}
completion(nil)
})
}
// Returns the group ids that a user belongs to
static func get(userUID:String, completion: @escaping (Array<String>) -> ()) {
let ref = FIRDatabase.database().reference().child("users").child(userUID).child("groups")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if let value = snapshot.value as? Dictionary<String,Any> {
completion(value.keys.sorted())
return
}
completion([])
})
}
}
导入UIKit
进口火基
类TableViewController:UITableViewController{
变量组=数组()
重写func viewDidLoad(){
super.viewDidLoad()
get(userUID:“alovelace”){(groups)in
在组中查找uid{
get(groupUID:uid,completion:{(Group)in)
如果让组=组{
打印(组)
self.groups.append(组)
}否则{
打印(“没有id为\(uid)的组”)
}
self.tableView.reloadData()
})
}
}
}
}
结构组{
变量uid:String
变量名称:String
变量成员:数组
初始化?(uid:String,dict:Dictionary){
警卫
让name=dict[“name”]作为字符串,
让users=dict[“members”]作为字典
否则{
归零
}
self.uid=uid
self.name=名称
self.members=Array()
对于用户中的(id,){
self.members.append(id)
}
}
//当给定组id时,返回一个组。
静态func get(groupUID:String,completion:@escaping(Group?)->()){
让ref=FIRDatabase.database().reference().child(“组”).child(groupUID)
ref.observeSingleEvent(of:.值,其中:{(快照))位于
如果let value=snapshot.value as?字典{
如果let group=group(uid:groupUID,dict:value){
完成(小组)
返回
}否则{
打印(“不完整的组数据”)
}
}
完成(无)
})
}
//返回用户所属的组ID
静态func get(userUID:String,完成:@escaping(Array)->()){
让ref=FIRDatabase.database().reference().child(“用户”).child(userUID).child(“组”)
ref.observeSingleEvent(of:.值,其中:{(快照))位于
如果let value=snapshot.value as?字典{
完成(value.keys.sorted())
返回
}
完成([])
})
}
}
当我开始(ds1 as!FIRDataSnapshot)时,没有键。据我所知,此快照仅引用我指定的路径(在用户中),因此没有组名。我遗漏了什么吗?请原谅我之前的回答,这个应该有用我编辑了它。它返回“alovelace”-“名称”,“组”下的键的名称。我想返回“组”下项目的实际名称-在这种情况下,“历史技术先锋”Firebase将通过单个打开的连接检索项目,因此,连接的开销很小。以这种方式(也称为客户端连接)检索合理数量的项并不像您想象的那么慢,因为请求是通过现有连接进行管道传输的。看见