Пагинация (Startafter) не работает в firestore и приложении Angular 9 - PullRequest
0 голосов
/ 05 августа 2020

При загрузке страницы я получаю данные из 15 записей, после прокрутки вниз я могу вызвать API, но он возвращает пустой массив (у меня всего 40 записей в моей базе данных firestore).

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

1 Ответ

0 голосов
/ 05 августа 2020

Пагинация Firestore не работает на основе смещения numeri c, но основана на так называемом документе курсоров / привязки. Из документации на startAfter:

Создает и возвращает новый запрос, который начинается после предоставленного документа (исключая). Начальная позиция определяется порядком запроса. Документ должен содержать все поля, указанные в порядке по этому запросу.

Итак, ваш вызов:

 .startAfter(config.page * config.limit)

Пытается начать после экземпляра документа config.page * config.limit. Поскольку это не снимок / ссылка документа, а число, он не знает, с какого документа начинать, поэтому ничего не возвращает.

Вместо передачи числового c смещения вам необходимо запомнить последний моментальный снимок документа с текущими результатами и передать его в startAfter.

Я настоятельно рекомендую прочитать документацию по разбивке данных на страницы с помощью курсоров запросов .

...