如何使用AngularFire、Firestore和Firebase实现分页到上一页。

12

抱歉,我看到这个问题已经以不同的方式在这里提问了很多次,例如:

但是,没有一个答案真正解释了解决方案或易于理解。

此外,我参考了许多教程,例如:

具体来说:

这是我迄今为止所做的:

let query = ref.orderBy(orderBy, asc ? 'asc' : 'desc').limit(limit);
        if (startAfter) {
          // Thiis works as it should
          query = query.startAfter(startAfter);
        }
        if (endBefore) {
          // This here does not work or give the correct results. I get the first page. 
          query = query.endBefore(endBefore);
        }
        return query;

所以:

query = query.startAfter(startAfter); 的效果符合预期。

然而:

query = query.endBefore(endBefore) 并没有在那个文档之前结束,我认为它会一直结束到限制位置。

2个回答

25

firebase@7.3.0 开始,您可以使用 Query.limitToLast(n: number) 方法 - 这使得在分页数据中向后移动变得更加容易。

您的实现细节可能看起来像这样:

function nextPage(last) {
   return ref.orderBy('age').startAfter(last.age).limit(3);
}

function prevPage(first) {
   return ref.orderBy('age').endBefore(first.age).limitToLast(3);
}

你认为这应该是正确的答案吗?我问这个问题是因为我还没有尝试过,也不知道是否存在任何差异和最重要的限制。 - Jimmy Kane
2
没有必要更改,我只是想确保选项在这里显示,因为它是SDK中的全新功能。仅适用于7.3或更高版本的应用程序。 - JeffD23
我会等一段时间,让用户适应你的东西,然后我会更改它,这样我们就可以涵盖我认为很大一部分的帮助。 - Jimmy Kane
limitToLast() 对我很有帮助(用于导航到上一页)。 - Faraz Ahmad
我把这个设为正确答案,因为你得到了大众的选择 :-D谢谢你 :-D - Jimmy Kane
为什么limitToLast会将最后两个结果也带出来?productRef.endBefore(getSnapOfLast).limitToLast(recordSize).get() - bitsedegitsek

10

所以我认为通过受到上述Github问题启发的注释解决了它:

假设您有这个数组并且正在进行升序排序

A,
B, 
C,
D,
E,
F, 

您的页面限制为2个结果

那么当您在第三页时,您应该有:

E,
F

现在您需要返回到上一页,要做的是:

  1. 反转排序顺序,使我们的数据为[F,E,D,C,B,A]
  2. 从当前查看页面的第一个文档后开始(在我们的例子中为E)
  3. 查询Firestore以获取结果(例如使用您的限制为2)。您应该以相反的顺序和在E之后开始获得[D,C]
  4. 反转以上数组,因此它将变为[C,D]
  5. 完成

1
@f.khantsis 嘿!Doom777?来自AGM地图?Dimitrios kanellopoulos在这里我们已经谈过了。这真是太糟糕了,更糟糕的是Firebase团队不会帮助解决这些问题。 - Jimmy Kane
2
谢谢你的想法。我一直在努力实现这个。 - neuraminidase7
1
嘿@JimmyKane,回答不错!他们甚至不想把这个问题称作“问题”:https://github.com/firebase/firebase-js-sdk/issues/479虽然我理解他们的NoSQL数据库结构无法完全处理这种方法,但他们至少应该对如何以体面的方式解决这个问题提出意见,但他们更倾向于简单地接受“Firestore并不是你的数据库”的事实,这很烦人,因为在Firebase中,没有SQL替代方案(或其他能够处理此方法的NoSQL)。 - Guilherme Matuella
1
谢谢Jimmy,我也将你的逻辑应用到我的vuexfire应用程序中。唯一的问题是第四步如何使用文档快照对象(而不是数组)来反转数组。 - Akin Hwan
我正在尝试为一个firestore应用程序实现分页,并找到了这个解决方案并进一步研究了它。我想说,虽然这是一个可行的解决方案,但你很容易就会超出使用限制。假设你有一个包含100个文档的集合,每页显示10个文档,现在你在最后一页。执行上一页意味着你将执行90次读取操作才能回到上一页。对于1000个文档,这将是990次读取操作。你明白我的意思吧。所以,如果有人要以这种方式实现分页,请注意。 - eugeneoei
@eugeneoei,你对页面大小设置了限制。这是可扩展的。请再次阅读登录信息。它说:“查询firestore以获取结果(例如使用2个限制)。您应该按相反顺序并从E之后开始,即[D,C]。”如果您不设置限制,那么您是正确的。但是,那样会使整个逻辑错误。 - Jimmy Kane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接