2016-06-26 4 views
1

私はコードが不足しているため、Firebaseがかなり新しくなっているので、「ここでどこから始めるべきか分かりません」ということをもっと試してみるのが欠けているわけではありません。新しい投稿のみを返すFirebaseクエリですか?

私は10分 "古い"以下の投稿のみを表示しようとしています。私は、毎晩クエリを送信するために、アプリでタイマーを実行するつもりです(問題があまり発生しないと仮定します)。現在の投稿が10分を超えていないことを確認します。彼らは、クエリはそれらを返すべきではありません。

ユーザーが投稿を作成したときにタイムスタンプが作成される場所を設定しました。

設定は次のとおりです。

Posts 
    02983094jfksdflkaj3l 
     timestamp: 23478923019 

私はorderByValueする必要があると仮定していますか?タイムスタンプで投稿を並べ替えて、それをある種類の制限で返しますが、そのすべてをどのようにマップするかはわかりません。

ここでは正しい方向のポイントを高く評価します。

ありがとうございます!

編集:私はもうコレクションビューに表示されている投稿を取得していません...そして、10分未満のクエリを満たす必要のある投稿数にかかわらず、1つしか返されません。

私は以下に示すように、スナップショットで.valueリターンを取得していません...タイムスタンプ値を返す必要があります。タイムスタンプスナッププリントに表示されます。

override func viewWillAppear(animated: Bool) { 
    let cutoff = UInt64(1000 * floor(NSDate().timeIntervalSince1970) - 10*60*1000); 
    let cutoffFloat = Float(cutoff) // <-- woudnlt take a UInt64 as an AnyObject. I assume its ok to just do this? 


    DataService.ds.REF_POSTS.queryOrderedByChild("timestamp").queryStartingAtValue(cutoffFloat).observeSingleEventOfType(.ChildAdded) { (snapshot: FIRDataSnapshot) in 
     print("child added") // <------- isn't ever getting called 
     self.Posts = [] 
     if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] { 

      for snap in snapshots { 

      print("timestamp snap: \(snap)") // <---- returns timestamp snap: Snap (timestamp) 23904819242 

         if let postDict = snap.value as? Dictionary<String, AnyObject> { 

        print(snap.value)// <----- Returns nothing 
        let key = snap.key 
        let post = Post(postKey: key, dictionary: postDict) 
        self.Posts.append(post) 

       } 
      } 
     } 

     self.collectionView.reloadData() 

}

私はそれが任意のヘルプですが、ここに私のコードだった場合、私はコレクションビューを移入する前に使っていたかわからない。ここで

DataService.ds.REF_POSTS.observeEventType(.Value) { (snapshot: FIRDataSnapshot) in 

     self.Posts = [] 
     if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] { 

      for snap in snapshots { 

       print(snap) 

       if let postDict = snap.value as? Dictionary<String, AnyObject> { 
        let key = snap.key 
        let post = Post(postKey: key, dictionary: postDict) 
        self.Posts.append(post) 
       } 
      } 
     } 

     print("got here") 
     self.collectionView.reloadData() 


    } 
+0

タイマーはおそらく不要で、過去10分間に1,024件の投稿があったと考えてください。これらの投稿のうち、どれくらいをお客様のクライアントに配信する必要がありますか?私が推測していることは、それらのすべてに興味があるかもしれないが、実際には一度に20件(たとえば)、あるいは最近の20件だけを表示したいということです。Firebaseは非同期であることを覚えておいてください。新しい投稿が自動的に通知されますので、常に最新の投稿が表示されます。ポーリングはFirebaseに作業をさせることで完全に排除することができます。 – Jay

+0

@Jay 友人のグループから一度に投稿がユーザーに表示されることは常に許可されます。実装しようとしている機能には10分のビットが重要です。限られた量の「ショータイム」を持つ投稿とやりとりすることがアプリのポイントとして表示される投稿がない場合は大丈夫です。 ユーザーの友だちの投稿から制限を9つだけ取り除くと、情報の洪水や何かの問題があってはいけませんか? 私はこれがこれについての最良の方法だと仮定しています。あなたはこのようにそれについて行くと何かが目障りに間違っているのを見ますか? – Noowoo

答えて

3

タイマーを実行し、10秒ごとに別のクエリを送信することは、リアルタイムデータベースの恐ろしい使用です。代わりに10分前からすべての投稿を尋ねて、クエリをアクティブにしておきます。 @ JustinMのコードからの借入

let ref = FIRDatabase.database().reference 
let cutoff = UInt64(1000 * floor(NSDate().timeIntervalSince1970) - 10*60*1000);  
ref.child("post") 
    .queryOrderedByChild("timestamp") 
    .queryStartingAtValue(cutoff) 
    .observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
     let post = Post(title: snapshot["title"], timestamp: snapshot["timestamp"]) 
     self.postsArray.append(post) 
    } 

    self.tableView.reloadData() 

    // start a timer that removes expired items from postsArray 
    NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "removeExpiredItems", userInfo: nil, repeats: true) 
}) 

そして、クライアント側では、あなたのタイマーを実行すると、彼らは「有効期限切れ」として投稿を捨てます。

func removeExpiredItems() { 
    let cutoff = UInt64(1000 * floor(NSDate().timeIntervalSince1970) - 10*60*1000) 
    while (self.postsArray.count > 0 && self.postsArray[0].timestamp < cutoff) { 
     // remove first item, because it expired 
     self.postsArray.removeAtIndex(0) 
    } 
    self.tableView.reloadData() 
} 
+0

これまでのところ助けてくれてありがとう。私は元の投稿の編集として追加したこのコードを実装しようとするいくつかの問題にぶち当たっています。あなたはそれを見てみることができますか? – Noowoo

+0

フランクに感謝します。私はコメント以外のこれを書く時間がなかった。これは間違いなく正解です。 – Jay

2

は、設定する方法をあります実行中のタイマー:

NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector "updateTime", userInfo: nil, repeats: true) 

} 
func updateTime() { 
    let currentTime = NSDate() 
    self.time = currentTime.description 

} 

最後の10分間の投稿のfirebaseを照会する:

let ref = FIRDatabase.database().reference 
//let x = currentTime - 10 minutes in equivalent time structure. For example, if by minutes, currentTime - 10. You put that in queryStartingAtValue. 
ref.child("post").queryOrderedByChild("timestamp").queryStartingAtValue("x").observeSingleEventOfType(.Value, withBlock: { snapshot in 
     self.postsArray.removeAll 
     for snap in snapshot.children { 
      let post = Post(title: snap["title"], timeStamp: snap["timestamp"]) 
      self.postsArray.append(post) 
     } 

     self.tableView.reloadData() 
    }) 

queryStartingAtValueは、指定した値以上のすべての投稿を表示します。

これを処理するいくつかのより良い方法がありますが、これはもう少し複雑ですが、これは良いスタートになるはずです.New Firebaseには素晴らしいドキュメントと例があります。ソート/フィルタリングの詳細については、データベース/データの検索に関するセクションを参照してください。

ご希望の方は、これを参考にしてください。ご不明な点がありましたら教えてください。

+0

uh。このクエリは正しく動作しません。.Childを追加すると、一度に1つの子ノードがキャプチャされるため、追加のスナップショットに対して反復処理を否定するスナップショットには1つしか存在しません。また、各呼び出しの後に配列を空にするので、1つのポストになります。また、1000のポストがあるかのようにテーブルが点滅する可能性があり、1000回連続してtableViewを更新します。また、x = 9amの場合、すべての投稿(8時50分〜9時)にオブザーバーが追加されます。その後、9時10分に再び実行された場合、9時10分から9時までのすべての監視員が8時50分から9時に追加されます。 – Jay

+0

だからあなたは何が最高だと思いますか? observeSingleEventOfType(.value)? – JustinM

+0

ええ、それはOPがタイマーと一緒に行くなら良いスタートです。しかし、それが事実なら、それは本当に多くのオーバーヘッドをアプリに追加し、Firebaseの目的を破っている。また、そのタイマーが1秒ごとに起動している場合、大量のデータを潜在的にプッシュする可能性があり、最後のデータが処理される前にデータが返されているという点で 'コールバック・ヘル'という問題が発生します。データの流れの背後にある思考過程とそれがどのように提示されるかは、おそらく再訪問されるべきです。 – Jay

関連する問題