Firebase查询在错误的时间运行

时间:2016-12-28 02:08:25

标签: ios swift firebase firebase-realtime-database

由于某种原因,当我运行以下方法时,第一个查询在方法完成后运行。我尝试使用调度块以强制查询首先运行,但查询永远不会运行然后应用程序只是冻结。如果你知道什么是错的,请告诉我。

没有调度组的方法:

func loadConversations() {
    let ref = FIRDatabase.database().reference()
    let convoRef = ref.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("conversations")
    var conversationID = [String]()
    print(1)
    convoRef.queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in
        let enumerator = snapshot.children
        print(2)
        while let rest = enumerator.nextObject() as? FIRDataSnapshot {
           print(3)
            if let id = rest.value as? String{
                conversationID.append(id)
                print(id)
            }
        }
    })
    print(4)
    print("size: \(conversationID.count)")
    for id in conversationID {
     print(5)
       ref.child("conversations").queryEqual(toValue: id).observeSingleEvent(of: .value, with: { (snapshot) in
      print(6)
            if let convo = snapshot.value as? [String : AnyObject] {
          print(7)
                let conversation = Conversation()
                conversation.conversationID = id
                conversation.name = "Temporary test name"
                self.Conversations.append(conversation)
            }
       })
        ref.removeAllObservers()
    }
    print(8)
    self.conversationTableView.reloadData()
    ref.removeAllObservers()

}

打印:

1
4
size: 0
8
2
3
-KZyMMzXmkQC_OF0T08_

使用调度组:

func loadConversations() {
    let dispatchGroup = DispatchGroup() 
    let ref = FIRDatabase.database().reference()
    let convoRef = ref.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("conversations")
    var conversationID = [String]()
    print(1)


    dispatchGroup.enter()
    convoRef.queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in

        let enumerator = snapshot.children
        print(2)
        while let rest = enumerator.nextObject() as? FIRDataSnapshot {
           print(3)
            if let id = rest.value as? String{
                conversationID.append(id)
                print(id)
                dispatchGroup.leave()
            }
        }


    })

    print(4)
    dispatchGroup.wait()
    print("size: \(conversationID.count)")

    for id in conversationID {
     print(5)
       ref.child("conversations").queryEqual(toValue: id).observeSingleEvent(of: .value, with: { (snapshot) in
      print(6)
            if let convo = snapshot.value as? [String : AnyObject] {
          print(7)
                let conversation = Conversation()
                conversation.conversationID = id
                conversation.name = "Temporary test name"
                self.Conversations.append(conversation)
            }
       })
    }
    print(8)
    self.conversationTableView.reloadData()
    ref.removeAllObservers()
}

打印

1
4

然后它只是冻结并等待。查询永远不会运行。

我不确定为什么查询似乎没有输入。输入查询后,它完全正常,但输入太晚了。任何帮助是极大的赞赏。谢谢!

1 个答案:

答案 0 :(得分:2)

这只是因为Firebase查询是在后台线程上执行的,因为它本质上是一个网络调用。因此,响应在您的方法完成后发出,否则UI将被阻止,直到响应来自Firebase

您需要在查询响应中编写一个闭包,以便在获得响应后立即执行代码块。

func loadConversations(completion:@escaping (Array<String>) -> Void) -> Void {
    let ref = FIRDatabase.database().reference()
    let convoRef = ref.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("conversations")
    var conversationID = [String]()
    print(1)
    convoRef.queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in
        let enumerator = snapshot.children
        print(2)
        while let rest = enumerator.nextObject() as? FIRDataSnapshot {
           print(3)
            if let id = rest.value as? String{
                conversationID.append(id)
                print(id)
            }
        }
        completion(conversationID)
    })
}

这会将您的通话发送回来自

内部的任何地方
loadConversations { (array) in

    //do something with this value and execute next query
}