2017-05-14 5 views
0

Firebase Database를 처음 사용하기 시작했으며 효율적으로 데이터를 쿼리하는 데 어려움을 겪고 있습니다. 나의 현재 데이터베이스 구조는 우리가이 예제를 참조 권장 데이터 구조에 대한 중포 기지 문서와 유사하다 :여러 개의 키가있는 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를 통해 루프를 만드는 것입니다, 다음 .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

을 참조하십시오. 아래로 (! FIRDataSnapshot으로 ds1) 키가 없습니다. 내 이해에서,이 스냅 샷은 사용자가 지정한 경로만을 참조하므로 그룹 이름이 없습니다. 내가 놓친 게 있니? –

+0

실례합니다. 이전 답변에 대한 답변입니다.이 답변은 편집해야합니다. –

+0

"alovelace"- "name", "groups"아래의 키 이름을 반환합니다. "그룹"아래에있는 항목의 실제 이름을 반환하려고합니다.이 경우에는 "Historical Tech Pioneers" –

관련 문제