Spark Spark - 4 months ago 64
Swift Question

How to retrieve data synchronously from Firebase?

I have two collections namely, Users and Questions.

Based on the user logged in using userId, I retrieve the

currQuestion
value from
users
collection.

Based on the
currQuestion
value, I need to retrieve the
question
document from Firebase
Questions
collection.

I've used the below code to retrieve userId

rootRef.child("0").child("users")
.queryOrderedByChild("userId")
.queryEqualToValue("578ab1a0e9c2389b23a0e870")
.observeSingleEventOfType(.Value, withBlock: { (snapshot) in

for child in snapshot.children {
self.currQuestion = child.value["currentQuestion"] as! Int
}
print("Current Question is \(self.currQuestion)")

//print(snapshot.value as! Array<AnyObject>)
}, withCancelBlock : { error in
print(error.description)
})


and to retrieve question

rootRef.child("0").child("questions")
.queryOrderedByChild("id")
.queryEqualToValue(currQuestion)
.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
for child in snapshot.children {
print(child.value["question"] as! String)
}

}, withCancelBlock: { error in
print(error.description)
})


But the above code executes asynchronously. I need to solution to make this synchronous or how to implement listeners so I can fire back the question query once the
currQuestion
value is changed?

Answer

Write your own method which takes in a completion handler as its parameter and waits for that block of code to finish. Like so:

 func someMethod(completion: (Bool) -> ()){
 rootRef.child("0").child("users")
    .queryOrderedByChild("userId")
    .queryEqualToValue("578ab1a0e9c2389b23a0e870")
    .observeSingleEventOfType(.Value, withBlock: { (snapshot) in

        for child in snapshot.children {
            self.currQuestion = child.value["currentQuestion"] as! Int
        }
        print("Current Question is \(self.currQuestion)")
        completion(true)
        //print(snapshot.value as! Array<AnyObject>)
    }, withCancelBlock : { error in
            print(error.description)
    })
}

And then whenever you want to call that function, call like so:

someMethod{ success in
if success{
//Here currValue is updated. Do what you want.
}
else{
//It is not updated and some error occurred. Do what you want.
}
}