web-dev-qa-db-ja.com

Firebaseからデータを時系列で適切に注文するにはどうすればよいですか

Firebaseからデータを注文しようとしているので、最新の投稿が一番上に表示されます(Instagramなど)が、正しく機能させることができません。サーバーのタイムスタンプを使用する必要がありますか? 「createdAt」フィールドはありますか?

func getPosts() {
    POST_REF.observeEventType(.Value, withBlock: { snapshot in
        guard let posts = snapshot.value as? [String : [String : String]] else {
            print("No Posts Found")
            return
        }

        Post.feed?.removeAll()
        for (postID, post) in posts {
            let newPost = Post.initWithPostID(postID, postDict: post)!
            Post.feed?.append(newPost)
        }
        Post.feed? = (Post.feed?.reverse())!
        self.tableView.reloadData()
        }, withCancelBlock: { error in
            print(error.localizedDescription)
    })
}
11
kerbelda

配列にreverse()のみを使用するだけでは、すべてを網羅するのに十分な方法ではありません。あなたが考える必要があるさまざまなことがあります:

  • データの取得中に制限し、append()を使用してからreverse()を使用します時間を節約するために。毎回すべてのアレイを削除する必要はありません。

  • スクロールトリガーまたはwillDisplayセルメソッド読み込み

はじめましょう。投稿の子を作成できますtimestampまたはdate/timeグローバル。 Instagram秒、週のように提供するには、UTC時間を使用することをお勧めします。だから私はこれを呼びます:(timeUTC

すべての投稿を並べ替えるには、since1970タイムスタンプを使用します。したがって、これを(timestamp)と呼び、別のノードを(reversedTimestamp)として保持して、タイムスタンプに-プレフィックスを追加することもできます。したがって、このノードに対してqueryOrderedを使用する場合。 yourQuery.queryLimited(toFirst: 5)を使用して最新の5件の投稿を処理できます。

1.timeUTCノードのUTC日付/時刻をSwift 3:で取得します

        let date = Date()
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
        formatter.timeZone = TimeZone(abbreviation: "UTC")
        let utcTimeZoneStr = formatter.string(from: date)

+0000は世界時を意味します。 http://time.is/tr/UTC を見てください。

2。1970年以降のタイムスタンプを取得して、投稿をSwift 3:

let timestamp = (Date().timeIntervalSince1970 as NSString).doubleValue
let reversedTimestamp = -1.0 * timestamp

これで、このようにFirebaseの投稿に保存できます。

"posts" : {
    "-KHLOy5mOSq0SeB7GBXv" : {
      "timestamp": "1475858019.2306"
      "timeUTC" : "2012-02-04 12:11:56 +0000"
    },
    "-KHLrapS0wbjqPP5ZSUY" : {
      "timestamp": "1475858010.1245"
      "timeUTC" : "2014-02-04 12:11:56 +0000"
    },

5 x 5の投稿を取得するので、viewDidLoadqueryLimited(toFirst:5)を実行しています。

let yourQuery = ...queryOrdered(byChild: "reverseTimestamp")
                   .queryEnding(atValue: "\(self.pageOnTimestamp)", childKey: "reverseTimestamp")

    yourQuery.observeSingleEvent(of: .value, with: { (snapshot) in

        if snapshot.value is NSNull {

            print("There is no post.")

        }
        else {

            yourQuery.queryLimited(toFirst: 5).observeSingleEvent(of: .value, with: { (snapshot) in

                self.posts.removeAll(keepingCapacity: true)

                for (i, snap) in snapshot.children.enumerated() {

                    if let postAllDict = snapshot.value as? [String: AnyObject] {
                        if let postDict = postAllDict[(snap as AnyObject).key as String] as? [String: AnyObject] {

                            let post = Post(key: (snap as AnyObject).key as String, postDict: postDict)
                            self.posts.append(post)
                        }
                    }
                }

                completion(true)
            })
        }
    })

ユーザーが最新の投稿に到達した場合は、以下のようにwillDisplayメソッドで処理でき、loadMore関数を呼び出すことができます。

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

   if self.posts.count - 1 == indexPath.row {
      // call loadMore function.
   }
}

LoadMore()関数では、最新の投稿のタイムスタンプを処理し、それと同じようにクエリを開始および終了できるため、配列の前に追加しながら、次の最初の5つの投稿を簡単に続行できます。

Swift 3をニース形式で変換するには、こちらをご覧ください: Swift 3-UTCから時間前のラベル、12時間/ 24時間のデバイス時間を考えて変更

13
iamburak

@tobeiosdevの回答に基づいて、データ構造を次のように定義します。

"posts" : {
"-KcOa8GXBl08V-WXeX8P" : {
  "author" : "@giovanny.piñeros",
  "hashtags" : [ "Hello", "World" ],
  "text" : "Hola Mundo!!!!!",
  "timestamp" : 5.08180914309278E8,
  "title" : "Hello World",
  "userid" : "hmIWbmQhfgh93"
}

タイムスタンプ属性を追加したことがわかるように、子が追加されたイベントを使用してデータをクエリすると、そのデータが投稿オブジェクトに渡され、テーブルビューがフィードする投稿の配列にそのオブジェクトが追加されます。

 self.posts.append(post)
 self.posts.sort(by: {$0.timestamp! > $1.timestamp!})
 self.tableViewFeed.reloadData()

並べ替え方法を使用して、最新から古いものへと、投稿の希望順にデータを並べ替えることができました。このアプローチが誰にでも役立つことを願っています:)。

1