【问题标题】:Creating a paginated chronological query in Firestore在 Firestore 中创建分页时间查询
【发布时间】:2018-03-28 15:19:29
【问题描述】:

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

我正在尝试创建一个本质上的新闻提要,从最旧的内容中排序最新的内容。这部分很简单,我使用:

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

检索新闻提要中的 3 个最新条目。我当时的想法是在下一个查询中,拉下提要中的下 3 个项目。因此,如果我们按年龄来计算,就这些项目的新旧程度而言,该系列中有 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,尽管试图告诉第二个查询从节点 3 开始

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

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

不幸的是,这也不起作用。 我也尝试传入整个快照项,并得到了错误 “来自 JS 的畸形调用:字段大小不同。 [[9,38,38,38],[0,0,1,0], 等等。”

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

任何帮助都会很大!谢谢

【问题讨论】:

  • 有人知道吗?
  • 你解决了吗?我现在也有同样的问题。

标签: javascript firebase google-cloud-firestore


【解决方案1】:

我有一个名为“books”的集合,其中包含一个名为“created”的字段,类型为 Timestamp。这不是一个字符串。这不是一个日期。请参阅the Timestamp docs。您需要在设置中指定要使用新的 Timestamp 类型而不是 Date 作为您的时间戳字段。 (见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

【讨论】:

  • 如何获取下三个查询?
  • @Ajay Malik,到目前为止,你为获得接下来的三个做了什么尝试?
  • 其实我想通了。非常感谢上述解决方案。
【解决方案2】:

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

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

例子:

    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
      })
    })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2021-08-17
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多