2016-08-12 14 views
1

firebaseに格納されている投稿をテーブルビューに読み込もうとしています。 .childAdded関数を使用して投稿を(最初から最後まで)投稿した順番で取得します。最初はうまくいったように見えましたが、今はもう動作しません。理由はわかりません。だから私は、投稿にタイムスタンプを追加し、queryOrderedByChild( "タイムスタンプ")を使用しました。まだ間違った順序だ!ここに私のコードは次のとおりです。クエリの最初のタイムスタンプ値の印刷が出しFirebaseのスナップショットが間違っている

posts.removeAll() 
    let ref = FIRDatabase.database().reference() 

    ref.child("Posts").queryOrderedByChild("timestamp").observeEventType(.ChildAdded, withBlock: { (snapshot:FIRDataSnapshot) in 

     print(snapshot.value!["timestamp"] as! Int) 
     if snapshot.value == nil { 
      return 
     } 
     let post = Post() 
     post.title = snapshot.value!["Title"] as? String 
     post.postType = snapshot.value!["postType"] as? Int 
     post.postDescription = snapshot.value!["Description"] as? String 

     if post.postType == 2 { 
      post.imageAURL = snapshot.value!["imageAURL"] as? String 
      post.imageBURL = snapshot.value!["imageBURL"] as? String 
     }else if post.postType == 3 { 
      post.imageAURL = snapshot.value!["imageAURL"] as? String 
      post.imageBURL = snapshot.value!["imageBURL"] as? String 
      post.imageCURL = snapshot.value!["imageCURL"] as? String 
     } 


     let createdByID = snapshot.value!["createdBy"] as! String 
     var username = String() 
     let usernameRef = FIRDatabase.database().reference().child("users").child(createdByID) 
     usernameRef.observeSingleEventOfType(.Value, withBlock: { (snapshot:FIRDataSnapshot) in 

      username = snapshot.value!["username"] as! String 
      post.createdBy = username 
      self.posts.append(post) 
      self.tableView.reloadData() 
      }, withCancelBlock: nil) 




      dispatch_async(dispatch_get_main_queue(), { 

       self.tableView.reloadData() 
      }) 


     }, withCancelBlock: nil) 


} 

1471008028 
1471007899 
1471007928 
1471007979 

を見てわかるように、最初のIntは、次の3つがあり、最高です昇順で正しく注文されていますが、なぜ最初は最高で最後ではないのですか?私はそれが何かと関係があるかどうかはわかりませんが、コードはviewDidLoadの内部で呼び出される関数の中にあります。

+0

私は、異なるユーザーアカウントから投稿を投稿しました。私は今気づいた、現在ログインしているユーザーの投稿は、常に最初に読み込まれたものですが、なぜですか?つまり、別のユーザーとしてログインして再度シミュレータを起動すると、順序が変更されますが、.ChildAdded関数はログインしたユーザーに関係なく、すべての投稿をロードするだけなので、 –

+0

これは[以前](http://stackoverflow.com/a/15723418/6680611)と尋ねられ、回答されています。 – cartant

+0

私は答えがちょっと古くて、間違っていれば正しいと思います。また、迅速にサンプルがないので、誰かが迅速な解決策を持っていたり、コードを編集して、それをやり遂げなければならない場合には素晴らしいかもしれません。 –

答えて

0

Firebase JavaScript child_addedイベントが順序どおりに発生しない理由を説明する既存のanswerがあります。これはまだ適用され、予期しない順序でスナップショットが配信される理由です。

これは奇妙に思えるかもしれませんが、これは実際に意図された動作です。

Firebaseは、ローカルイベントがサーバーと最初に通信することなく直ちに起動できるように、child_addedイベントが常にソート順で呼び出されることを保証しません。

正しい順序に受信したスナップショットを配置するためには、スナップショットを(それが参照する答えにprevChildNameとも呼ばれます)に付随前の兄弟キーが必要です。前の兄弟キーを取得するには、observeEventType:andPreviousSiblingKeyWithBlock:を使用する必要があります。

observeEventType:andPreviousSiblingKeyWithBlock:のFirebaseのマニュアルでは、受信したスナップショットを整理するために前の兄弟キーをどのように使用すべきかを明確にしていません。例の目的のために

、配列内のスナップショットを保存し、注文するには、それぞれに次の操作を実行する必要がありますスナップショット受信:受信スナップショットがnullの前の兄弟キーを持っている場合

  • をそれを配列の先頭に追加します。
  • それ以外の場合は、受信したスナップショットに付随する前の兄弟キーと等しいkeyを持つスナップショットをアレイ内に見つけ、見つかったスナップショットの後に受信したスナップショットをアレイに挿入します。
  • 前の兄弟キーにスナップショットがない場合は、受信したスナップショットを配列の末尾に追加します。
+0

現時点では、私はその解決策を試す時間がありませんが、私は本当にあなたの答えを感謝し、私はそれが動作するはずだと思うので、正解としてそ​​れをマークしています!どうもありがとう!それでも私はタイムスタンプ付きのorderedByChildが動作しない理由を知りません! –

+0

それは痛みです、私は知っています。それはそれだけです - 保証はありません。 Firebaseの[AngularFire2](https://github.com/angular/angularfire2/blob/2.0.0-β2/src/utils/firebase_list_factory.ts#L150-L165)のソースを見ると、そこには 'reduce'ベースのメカニズムがあります。 – cartant

+0

タイムスタンプを使用してorderedByChildが機能しない理由が分かりますか?私がドキュメントを読んでいる限り、スナップショットを昇順で注文する必要がありますか?それはなぜ機能しないのですか? –

関連する問題