如何从Firebase同步检索数据? [英] How to retrieve data synchronously from Firebase?

查看:145
本文介绍了如何从Firebase同步检索数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个集合,即用户和问题。



根据使用userId登录的用户,我检索 currQuestion $ c c c 值,我需要从Firebase 问题集合中检索问题文档。



我使用下面的代码来检索userId

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

for snapshot.children {
self.currQuestion = child.value [currentQuestion] as!Int
}
print(当前问题是\(self .currQuestion))

//print(snapshot.value as!Array< AnyObject>)
},withCancelBlock :$错误
print(error.description)
})

检索问题

  rootRef.child(0)。child(questions)
.queryOrderedByChild( id)
.queryEqualToValue(currQuestion)
.observeSingleEventOfType(.Value,withBlock:
中的{(snapshot))为snapshot.children中的子项{
print(child.value [ 问题]为!字符串)
}

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

但上述代码异步执行。我需要解决方案来使这个同步或如何实现监听器,所以一旦 currQuestion 值被更改,我可以反驳问题查询。

解决方案

编写自己的方法,将完成处理程序作为参数,并等待该代码块完成。如下所示:

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

为snapshot.children中的孩子{
self.currQuestion = child.value [currentQuestion] as!Int
}
print(当前问题是\\ \\(self.currQuestion))
completion(true)
//print(snapshot.value as!Array< AnyObject>)
},withCancelBlock:{error in
print (error.description)
})
}

然后每当你想要调用该函数,调用如下:

  someMethod {
如果成功{
//这里currValue已更新。做你想要的
}
else {
//没有更新,发生一些错误。做你想要的
}
}

完成处理程序通常用于等待一个代码完成执行完毕。 P.S。只要它们不阻塞主线程,通过添加如上所示代码的完成处理程序来使异步请求同步。



它只是等待您的 currValue 先被更新(接收数据 async ),然后当您调用 someMethod 像我所显示的那样,并且由于函数的最后一次唯一参数 someMethod 是一个闭包(aka,尾随Closure ),您可以跳过括号并调用它。 这里是关于闭包的一个很好的阅读。而且由于关闭是类型(Bool) - >(),所以在完成任务完成之后,您只需要在 someMethod 在我的代码中,,然后在调用它时,用成功(你可以使用任何你想要的单词)将会类型为 Bool ,因为它被声明为这样,然后在函数调用中使用它。希望它有帮助。 :)


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?

解决方案

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

Completion handlers are usually used to wait for a block of code to finish executing completely. P.S. As long as they don't block the main thread, asynchronous requests are made to act synchronous by adding a completion handler like the code shown above.

What it simply does is wait for your currValue to be updated first (receiving the data async from the server) and then when you call someMethod like how I've shown, and since the last and only parameter to the function someMethod is a closure (a.k.a, trailing Closure ), you can skip the parenthesis and call it. Here is a good read about closures. And since the closure is of type (Bool) -> (), you just tell your someMethod when the task is completed which is done like completion(true) in my code, and then while calling it, you call it with success (You can use any word you want) which WILL BE of type Bool as it is declared like so, And then use it in the function call. Hope it helps. :)

这篇关于如何从Firebase同步检索数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆