Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 查询Firebase数据库中的多个密钥_Ios_Swift_Firebase_Firebase Realtime Database - Fatal编程技术网

Ios 查询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": {

我刚刚开始使用Firebase数据库,在高效查询数据方面遇到了一些麻烦。我当前的数据库结构类似于Firebase文档中推荐的数据结构,我们在其中看到以下示例:

// 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将通过单个打开的连接检索项目,因此,连接的开销很小。以这种方式(也称为客户端连接)检索合理数量的项并不像您想象的那么慢,因为请求是通过现有连接进行管道传输的。看见