2017-05-14 45 views
0

我剛剛開始使用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電話爲每個人獲取名稱。但是如果我有一組非常龐大的用戶羣呢?理想情況下,我不希望進行如此多的數據庫調用,只需要在一個調用中完成。這種數據結構可能嗎?

+0

Firebase將通過單個打開的連接檢索項目,因此連接的開銷很小。以這種方式(也稱爲客戶端連接)檢索合理數量的項目並不像您想象的那麼慢,因爲請求是通過現有連接進行流水線處理的。見http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786 –

回答

0

這是我建議你做。這將使用用戶所屬的組樹中的所有數據填充組數組。

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

當我得到(ds1 as!FIRDataSnapshot),沒有密鑰。據我瞭解,這個快照只引用我指定的路徑(在用戶中),所以它沒有組名。我錯過了什麼嗎? –

+0

對不起,以前的答案,這一個應該工作我編輯它。 –

+0

這將返回「alovelace」 - 「名稱」,「組」下的鍵的名稱。我希望返回「組」中的項目的實際名稱 - 在這種情況下,「歷史技術先驅」 –