分页 (Startafter) 在 firestore 和 Angular 9 App 中不起作用

Pagination (Startafter) is not working in firestore and Angular 9 App

在页面加载时我得到了 15 条记录的数据,向下滚动后我可以调用 API 但它返回空数组。(我的 firestore 数据库中总共有 40 条记录)。

// Service.ts
getUsers(config: any) {
    return this.firestore
    .collection(
      'users',
      ref => ref
      .where('country', '==', 'India')
      .orderBy('lastlogin')
      .startAfter(config.page * config.limit)
      .limit(config.limit)
    )
    .snapshotChanges();
  }

// Component

getUsers() {
    this.loader = true;
    this.userService.getUsers(this.config).subscribe((res: any) => {
      this.loader = false;
      const data = res.map((e: any) => ({
        id: e.payload.doc.id,
        ...e.payload.doc.data()
      }));
      this.usersCollection = this.usersCollection.concat(data);
    });

// Infinite Scroll
onScroll() {
    this.config.page += 1;
    this.getUsers();
  }

我的解决方案

唯一的问题是第一次 lastVisible 没有数据,必须设置为 0。

getUsers(config: any, lastVisible) {
    const { doc } = lastVisible.payload ? lastVisible.payload : { doc: 0}
    return this.firestore
    .collection(
      'users',
      ref => ref
      .where('country', '==', 'India')
      .orderBy('lastlogin')
      .startAfter(doc)
      .limit(config.limit)
    )
    .snapshotChanges();
  }

// Component

getUsers() {
    this.loader = true;
    this.userService.getUsers(this.config, this.lastVisible).subscribe((res: any) => {
      this.loader = false;
      this.lastVisible = res[res.length - 1];
      const data = res.map((e: any) => ({
        id: e.payload.doc.id,
        ...e.payload.doc.data()
      }));
      this.usersCollection = this.usersCollection.concat(data);
    });

Firestore 分页不基于数字偏移量工作,而是基于 so-called cursors/anchor 文档。来自 startAfter 的文档:

Creates and returns a new Query that starts after the provided document (exclusive). The starting position is relative to the order of the query. The document must contain all of the fields provided in the orderBy of this query.

所以你的电话:

 .startAfter(config.page * config.limit)

尝试在文档实例 config.page * config.limit 之后启动。由于这不是文件 snapshot/reference 而是一个数字,它不知道从什么文件开始,所以它 returns 什么都没有。

无需传递数字偏移量,您需要记住当前结果的最后一个文档快照并将其传递到 startAfter

我强烈建议阅读有关 paginating data with query cursors 的文档。