Есть ли способ разбить данные firebase на страницы без моментального снимка?

# #javascript #firebase #google-cloud-firestore

Вопрос:

У меня есть коллекция firebase под названием activity с 4 документами внутри, с отметками времени 2, 3, 4 и 5 часов.

Когда я спрашиваю об этом так

 let postsQuery = firebase
      .firestore()
      .collection(`activity`)
      .orderBy("timestamp", "desc")
      .limit(2);
 

Я правильно понял сообщения на 5 и 4 часа.

Однако, когда я снова вызываю функцию со следующим условным:

 // oldest post is the 4 o'clock document
if (oldestPost) {
      postsQuery = postsQuery.startAfter(oldestPost);
    }
 

Я снова получаю документы 4 и 5. Если я изменю startAfter на любой другой фильтр, мне вернут 0 документов.

Поэтому мой вопрос в том, просто ли я делаю это неправильно, ИЛИ я не могу передать document.data() в качестве фильтра, и вместо этого мне нужно передать исходный документ?

Комментарии:

1. По-видимому, не вызов .data() в документе, а использование его в качестве самого старого сообщения сработало. ура!

2. Простите, но … .. Мне любопытно , если вы решили свой собственный вопрос, а также фрагмент кода, в котором вы обычно звонили .data() , не могли бы вы обновить свой вопрос исходным .data() кодом, чтобы мы могли понять контекст вашего комментария? И, знаете, если бы вы также могли опубликовать это в ответе и отметить как принятое, это помогло бы другим людям, сталкивающимся с подобными проблемами. Пожалуйста, и спасибо вам.

Ответ №1:

Итак, отвечая на мои собственные вопросы: когда я получал свои сообщения, я просто сохранял их в ID-карте

 postsQuery
.get()
.then((documents) => {
    const typeIdToDocument = {};
    documents.forEach((document) => {
        const data = document.data();
        typeIdToDocument[document.id] = { id: document.id, ...data };
    });
 

Затем, когда я передал в startAfter, я использовал результат .data() поста.
Однако это сработало, когда-
А) Я передал исходный документ firebase, а не версию .data()
ИЛИ Б) Я передал метку времени Firebase, а не полный документ

 postsQuery = postsQuery.startAfter(oldestFirebaseTimestamp);
 

Ответ №2:

Есть две перегрузки startAfter :

  1. startAfter ( snapshot : DocumentSnapshot < any > ) , который я рекомендую вам использовать всякий раз, когда вы можете
  2. startAfter ( ... fieldValues : any [] ) , в который вы можете передать только значения полей документа для последующего запуска.

Причина, по которой я рекомендую первую перегрузку, заключается в том, что могут быть случаи, когда у вас есть несколько документов с одним и тем же значением поля. Первая перегрузка в этом случае достаточно умна, чтобы использовать идентификатор документа для устранения неоднозначности между ними и не возвращать никаких перекрывающихся документов. Вторая перегрузка не может этого гарантировать.