使用 ID 列表的 Firebase 查询 (iOS)

Firebase query using a list of ids (iOS)

我有一个包含多个 ID 的 NSArray。在 Firebase 中有没有一种方法可以获取数组中具有 id 的所有对象?

我正在构建一个餐厅评级应用程序,它使用 GeoFire 检索附近的餐厅。我的问题是 GeoFire 只有 returns 附近餐厅的 id 列表。有什么办法可以用 ID 查询所有对象吗?

不,您不能像在 Firebase 中那样进行批量查询。

您将需要遍历您的餐厅 ID 并使用 observeSingleEvent 查询每个餐厅 ID。例如:

let restaurantIDs: NSArray = ...
let db = FIRDatabase.database().reference()
for id in restaurantIDs as! [String] {
    db.child("Restaurants").child(id).observeSingleEvent(of: .value) {
        (snapshot) in
        let restaurant = snapshot.value as! [String: Any]
        // Process restaurant...
    }
}

如果您担心性能,Firebase 可能 能够将所有这些 observeSingleEvent 调用分组并将它们作为批次发送到服务器,这可能会回答您的问题毕竟是原始问题 ;-)

我知道这个答案被认为是可以接受的,但我使用 promise kit 和方法 frank posted 与他的 javascript link 取得了非常好的成功只是想分享 swift 版本

所以我有一个附加到 post 的用户 ID 列表,如下所示: 这些方法也在我的 post class 中,在那里我可以从 firebase

访问 post id
// this gets the list of ids for the users to fetch ["userid1", "userid2"....]



func getParticipantsIds() -> Promise<[String]> {

    return Promise { response in
        let participants = ref?.child(self.key!).child("people")
        participants?.observeSingleEvent(of: .value, with: { (snapshot) in
            guard let snapshotIds = snapshot.value as? [String] else {
                response.reject(FirebaseError.noData)
                return
            }
            response.fulfill(snapshotIds)
        })

    }
}




// this is the individual query to fetch the userid


 private func getUserById(id:String) -> Promise<UserData> {
       return Promise { response in

           let userById = dbRef?.child("users").child(id)
           userById?.observeSingleEvent(of: .value, with: { (snapshot) in
               guard let value = snapshot.value else {
                   response.reject(FirebaseError.noData)
                   return
               }
               do {
                   let userData = try FirebaseDecoder().decode(UserData.self, from: value)
                   response.fulfill(userData)
               } catch let error {
                   response.reject(error)
               }
           })

       }
   }


// this is the where the magic happens


func getPostUsers(compeltion: @escaping (_ users:[UserData], _ error:Error?) -> ()){

    getParticipantsIds().thenMap { (id) in
        return self.getUserById(id: id)
    }.done { (users) in
        compeltion(users, nil)
    }.catch({ error in
        compeltion([], error)
    })

}