查询Firebase数据库以获取多个密钥

时间:2017-05-14 23:39:08

标签: 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": {
         // 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来获取名称。但是,如果我为用户提供了大量的组,该怎么办?理想情况下,我不想进行如此多的数据库调用,只需在一次调用中完成。这种数据结构有可能吗?

2 个答案:

答案 0 :(得分:0)

你可以这样做:

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)
    }
})

答案 1 :(得分:0)

我建议你这样做。这将使用用户所属的组树内的所有数据填充groups数组。

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([])
        })
    }
}