Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase query using a list of ids (iOS)

I have an NSArray containing multiple ids. Is there a way in Firebase where I can get all the object with the ids in the array?

I am building a restaurant rating app which uses GeoFire to retrieve nearby restaurants. My problem is that GeoFire only returns a list of ids of restaurant that are nearby. Is there any way i can query for all the object with the ids?

like image 749
Abbin Varghese Avatar asked Apr 10 '17 12:04

Abbin Varghese


2 Answers

No, you can't do a batch query like that in Firebase.

You will need to loop over your restaurant IDs and query each one using observeSingleEvent. For instance:

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

If you are worried about performance, Firebase might be able to group all these observeSingleEvent calls and send them as a batch to the server, which may answer your original question after all ;-)

like image 59
Paulo Mattos Avatar answered Nov 13 '22 15:11

Paulo Mattos


I know that this answer is considered accepted but I have had really good success using promise kit with the method frank posted with his javascript link Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly and just wanted to share the swift version

So I have a list of users ids that are attached to a post like this: also these methods are in my post class where I have access to the post id from firebase

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

}
like image 45
Barrett Avatar answered Nov 13 '22 14:11

Barrett