2016-07-17 11 views
0

私は2つのコレクション、すなわちユーザーと質問を持っています。Firebaseから同期してデータを取り出す方法は?

userIdを使用してログインしたユーザーに基づいて、currQuestion値をusersコレクションから取得します。

currQuestionの値に基づいて、Firebase Questionsコレクションからquestionというドキュメントを取得する必要があります。

私がユーザID

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値が変更されたら質問クエリーを戻すことができますか?

+3

必要な処理を行うには、補完ブロックを使用します。同期しようとしないでください – Paulw11

答えて

5

パラメータとして完了ハンドラを取り込み、そのコードブロックが完了するのを待つ独自のメソッドを記述します。これと同じように:

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.303。メインスレッドをブロックしない限り、上記のコードのような補完ハンドラを追加することによって、非同期要求が同期動作するようになります。

それは単にあなたが最初に更新する(サーバからデータasyncを受信)とcurrValue待つれない何を、あなたは私が示されてきたかのようにsomeMethodを呼び出し、そしてときに関数someMethodへの最後のパラメータのみ以来クロージャ(別名クロージャ)である場合は、かっこをスキップして呼び出すことができます。 Hereは閉鎖についてよく読んでいます。クロージャはタイプ(Bool) - >()であるため、コードがcompletion(true)のように完了したら、someMethodに伝えてから、successでコールします。あなたが望む言葉)ブールのように宣言されているので、それを関数呼び出しで使用します。それが役に立てば幸い。 :)

+0

コードの第2部分について説明できますか?または、補完ハンドラを説明する有望なソースを教えてください。 – Spark

+1

私はあなたの質問に答えるために私の答えを編集しました。あなたが何かを理解していないかどうか聞いてみてください。 :) – Dershowitz123

+0

私はフォローアップの質問があります。私は、xCodeにネイティブな性質のように、UICollectionViewをロードする前にplistデータが完全にロードされるという主な事実のために、最初はシームレスに機能するデータソースのplistを最初に使用したアプリケーションを持っています。 Firebaseからデータが取得されている間にコードが前進し続けるので、Firebaseをデータソースとして使用したいので、ビューが空のときにデータを取得する前にUIViewController viewdidload関数が呼び出されます。最初にFirebaseからデータを取得するまでビューを強制的にロードしないでください。 –

関連する問題