【问题标题】:How to retrieve data synchronously from Firebase?如何从 Firebase 同步检索数据?
【发布时间】:2016-07-17 02:16:46
【问题描述】:

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

基于使用 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<AnyObject>)
        }, 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 值后回火问题查询?

【问题讨论】:

  • 使用完成块做任何你需要的事情。不要尝试同步写入

标签: ios swift events firebase-realtime-database


【解决方案1】:

编写您自己的方法,该方法将完成处理程序作为其参数并等待该代码块完成。像这样:

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

然后每当你想调用那个函数时,像这样调用:

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

完成处理程序通常用于等待代码块完全执行完毕。 P.S. 只要它们不阻塞主线程,异步请求就会通过添加一个完成处理程序(如上面显示的代码)来进行同步操作。

它所做的只是等待你的currValue首先被更新(从服务器接收数据async)然后当你像我展示的那样调用someMethod时,从最后也是唯一的函数 someMethod 的参数是一个闭包(也称为 trailing Closure ),您可以跳过括号并调用它。 Here 是一本关于闭包的好书。而且由于闭包的类型是 (Bool) -> (),所以您只需告诉您的 someMethod 任务何时完成,就像我的代码中的 completion(true) 一样,然后在调用它时,您使用 @987654330 调用它@ (你可以使用任何你想要的词) WILL BE 的类型是 Bool,因为它是这样声明的,然后在函数调用中使用它。希望能帮助到你。 :)

【讨论】:

  • 你能解释一下代码的第二部分吗?或者向我指出任何解释完成处理程序的有希望的来源?
  • 我已经编辑了我的答案来回答你的问题。如果您有不明白的地方,请随时询问。 :)
  • 所以我有一个后续问题。我有一个应用程序,它最初使用 plist 作为它无缝工作的数据源,因为 plist 数据将在加载 UICollectionView 之前完全加载,这也是 xCode 的本机性质。我现在想利用 Firebase 作为导致问题的数据源,因为代码在从 Firebase 中提取数据时不断向前移动,因此在检索数据之前调用 UIViewController viewdidload 函数,因此当视图为空白时!在首先从 Firebase 检索数据之前,如何强制视图不加载?
猜你喜欢
  • 2018-04-04
  • 2017-01-11
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多