2016-12-28 87 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 
} 
稱爲