如何从Firebase同步检索数据?
我有两个集合,即用户和问题。
根据使用userId登录的用户,我从users
集合中检索currQuestion
值。
根据currQuestion
值,我需要从Firebase Questions
集合中检索question
文档。
我使用下面的代码来检索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) }, withCancelBlock : { error in print(error.description) })
并检索问题
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) })
但是上面的代码是异步执行的。 我需要解决方案使这个同步或如何实现监听器,以便我可以在currQuestion
值更改后重新启动问题查询?
编写自己的方法,将完成处理程序作为参数,并等待该代码块完成。 像这样:
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) }, withCancelBlock : { error in print(error.description) }) }
然后,只要你想调用该函数,就这样调用:
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. } }
完成处理程序通常用于等待代码块完全执行。 PS只要它们不阻塞主线程,异步请求就会通过添加完成处理程序来实现同步,就像上面显示的代码一样。
它只是等待你的currValue
首先被更新(从服务器接收数据async
)然后当你调用someMethod
就像我已经显示的那样,并且因为函数someMethod
的最后一个也是唯一的参数是一个闭包(也就是说, 尾随Closure ),你可以跳过括号并调用它。 这是一个关于闭包的好读物。 因为闭包是类型(Bool) – >(),所以你只需要告诉你的someMethod
什么时候完成任务就像在我的代码中completion(true)
一样,然后在调用它时,你success
调用它(你可以使用你想要的任何单词,它将是Bool类型,因为它是这样声明的,然后在函数调用中使用它。 希望能帮助到你。 🙂