2016-12-28 101 views
1

由于某些原因,当我运行以下方法时,第一个查询在方法完成后运行。我尝试使用调度块来强制查询先运行,但查询从不运行,应用程序完全冻结。如果你知道什么是错的,让我知道。Firebase查询在错误时间运行

方法,无需调度组:

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 

但它只是冻结和等待。查询从不运行。

我不知道为什么查询只是不显示输入。当输入查询时,它工作得很好,但输入太迟。任何帮助是极大的赞赏。谢谢!

回答

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 
} 
称为