在Firestore中创建分页的时间顺序查询

时间:2017-10-17 02:22:04

标签: javascript firebase google-cloud-firestore

希望这是一个使用Firestore查询的相对简单的问题

我正在尝试创建一个基本上是新闻源,从最旧的内容中排序最新的内容。那部分很简单,我用:

var first = db.collection("feeds/0/active").orderBy("timestamp", "desc").limit(3);

检索新闻Feed中的3个最新条目。我的想法是在下一个查询中,下拉Feed中的下三个项目。因此,如果我们按年龄计算,那么该系列中的新产品将是4,5,6。

为此,我抓住查询一中的最后一项,并将该节点的时间戳作为我在查询2中的值的起点:

  var first = db.collection("feeds/0/active").orderBy("timestamp", "desc").limit(3);

      first.get().then(function (documentSnapshots) {
      // Get the last visible document
      var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1];


      var next = db.collection("feeds/0/active").orderBy("timestamp", "desc").startAt(lastVisible.data().timestamp).limit(3);
      next.get().then(function(docSn){
        console.log("SECOND QUERY!")
        docSn.forEach(function(doc) {
          console.log(doc.data().message)
        })
      })

此代码的结果返回与第一个查询返回相同的结果,即节点1,2,3,尽管尝试告诉第二个查询从node3开始

我也试过传入一个javascript对象:

  var datevalue = Date.parse(lastVisible.data().timestamp)    
  var next = db.collection("feeds/0/active").orderBy("timestamp", "desc").startAt(datevalue).limit(3);

遗憾的是,这也行不通。 我也试过传递整个快照项,并得到了错误 “来自JS的Malforormed Calls:字段大小不同。 [[9,38,38,38],[0,0,1,0], 等。“

不知道从哪里开始,因为我已经阅读了文档和任何示例,我可以找到并且似乎无法弄明白。我能想到实现这一点的唯一另一种方法是使用云函数在创建时为每个节点编号..但这感觉很糟糕

任何帮助都会很大!感谢

2 个答案:

答案 0 :(得分:0)

您是否正在检查返回的整个列表?或者,只是第一个节点?

如果使用startAt,则第二个列表中的第一个节点将是第一个列表中的最后一个节点(docs)。我建议使用startAfterdocs)。

示例:

    var db = firebase.firestore()
    var query = db.collection('feeds/0/active').orderBy('timestamp', 'desc').limit(3)
    query.get().then((firstSnapshot) => {
      var first3 = snapshot.docs
      query.startAfter(first3[2]).get().then((nextSnapshot) => {
        var next3 = snapshot.docs
      })
    })

答案 1 :(得分:0)

我有一个名为“ books”的馆藏,其字段名为“创建”的类型为时间戳。这不是字符串。这不是一个日期。请参阅the Timestamp docs。您需要在设置中指定要使用新的时间戳类型而不是日期作为时间戳字段。 (请参见docs for firestore settings

启动Firestore并设置TimestampsInSnapshots设置的示例:

   var firebaseApp = firebase.initializeApp({
        apiKey: [APIKEY],
        authDomain: [FIREBASEAPPDOMAIN],
        projectId: [PROJECTID]
   });

   var firestore = firebase.firestore();
   var settings = { timestampsInSnapshots: true }; // force Timestamp object instead of Date

   firestore.settings(settings);

完成此操作后,我运行了以下代码,并得到了预期的结果。第一个查询返回三个结果。最新的,最新的。 第二个查询返回下三个项目。

var first = db.collection('books').orderBy("created", "desc").limit(3);
console.log("FIRST QUERY!")
first.get().then(function(documentSnapshots) {    
    documentSnapshots.forEach(function (doc) {
        console.log(doc.data().created.toMillis())
    });
    // Get the last visible document
    var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];

    var next = db.collection('books').orderBy("created", "desc")
         .startAfter(lastVisible.data().created).limit(3);
    next.get().then(function (docSn) {
        console.log("SECOND QUERY!")
        docSn.forEach(function (doc) {
            console.log(doc.data().created.toMillis())
        });
    });
});

上面代码中的控制台:

FIRST QUERY!
1540573716371
1540573676652
1540573668643

SECOND QUERY!
1540573658893
1540573536420
1540536647891