Firestore startAfter последний моментальный снимок не работает, если 2 или более документа имеют одинаковое значение поля - PullRequest
0 голосов
/ 10 ноября 2019

У меня есть коллекция с именем 'test', в которой есть несколько документов. Каждый документ имеет уникальное имя и числовое поле. Я реализовал разбиение на страницы с помощью курсора запроса. Запрос для получения исходных документов выглядит следующим образом:

let lastDocument={};
 ref.collection("test").orderBy('number', 'desc').limit(3).get()
  .then(snapshot => {
    lastDocument = snapshot.docs[snapshot.docs.length-1];
  })
  .catch(err => {
    console.log("Error getting documents", err);
  });

После получения lastDocument я разбиваю его на страницы следующим образом:

ref.collection("test").orderBy('number', 'desc').startAfter(lastDocument).limit(3); //lastDocument has the last document of the snapshot that was retrieved.

В моей коллекции, если есть 2 или более документовкоторые имеют то же значение поля «число», то я не получаю этот документ в результате запроса. Принимая во внимание, что если я изменю значение поля «число», чтобы сделать все документы уникальными, я получу все результаты в пакетном режиме (в соответствии с предложением limit).

Это упомянуто в документеКроме того, если несколько полей имеют одинаковое значение, запрос не будет работать https://firebase.google.com/docs/firestore/query-data/query-cursors#paginate_a_query

Как мне изменить запрос, чтобы получить все документы в результате, даже если 2 или болеедокументы имеют те же значения для поля, используемого в orderBy?

Я использую:

"react-native-firebase": "^5.5.6", "react-native": "^0.59.8", "firebase": "^6.6.1",

Обновление: я проверил запросы на JSbin и онвозвращает правильные результаты. У меня есть проблемы, когда я использую его в реагировать нативное приложение с библиотекой реагировать-родной-firebase. Шаблон, который я до сих пор распознал, выглядит следующим образом: скажем, есть документы, подобные следующим: {id: a, num: 1}, {id: b, num: 2}, {id: c, num: 2},{id: d, num: 2}, {id: e, num: 3}, {id: f, num: 4} Затем, если я запрашиваю первый набор с помощью orderBy ('num', 'desc') и limitкак 2, я получу [а, б]. Теперь, если я сделаю запрос с последним документом startAfter как 'b' и ограничу как 2, то после b будут пропущены все документы, которые имеют num такое же, как у b (то есть 2). Итак, он пропустит документ [c, d] и вернет меня [e, f]. Это прекрасно работает на jsbin, но не на native-реактивах с использованием библиотекиact-native-firebase.

Точный вывод для кода здесь на реагирующем нативе приведен ниже:

"Получил все результаты"

"wbXwyLJheRfYXXWlY46j => {\" index \ ": 2, \" number \ ": 2}"

"kGC5cYPN1nKnZCcAb9oQ => {\ "index \": 6, \ "number \": 2} "

" 8Ek8iWCDQPPJ5s2n8PiQ => {\ "index \": 4, \ "number \": 2} "

"mr7MdAygvuheF6AUtWma => {\" index \ ": 1, \" number \ ": 1}"

"RCO5SvNn4fdoE49OKrIV => {\" index \ ": 3, \" number \ ":1} "

" CvVG7VP1hXTtcfdUaeNl => {\ "index \": 5, \ "number \": 1} "

" Получил первую страницу "

" wbXwyLJheRfYXXWlY46j=> {\ "index \": 2, \ "number \": 2} "

" kGC5cYPN1nKnZCcAb9oQ => {\ "index \": 6, \ "number \": 2} "

"Получил вторую страницу"

"mr7MdAygvuheF6AUtWma => {\" index \ ": 1, \" number \ ": 1}"

"RCO5SvNn4fdoE49OKrIV => {\"index \ ": 3, \" number \ ": 1}"

Обратите внимание, что оно пропущено: "8Ek8iWCDQPPJ5s2n8PiQ => {\ "index \": 4, \ "number \": 2} "

Обнаружена еще одна проблема в библиотекеact-native-firebase: Если естьэто структура карты в документах, как показано ниже:

{
 subscribedUsers:{
 +1656666:true,
 +1657878:false,
 +1677676:true
 }
}

Теперь, если я выполню запрос, как показано ниже:

db.collection ("ownerUsers"). where (subscribedUsers.${phonenumber}, '==', true) .limit (3) .get ();

Запрос возвращает 3 результата. Теперь, если я попытаюсь получить следующие 3 результата, используя предложение startAfter, как показано ниже, он отлично работает с firebase, но не работает с библиотекойact-native-firebase:

db.collection ("ownerUsers"). where (subscribedUsers. $ {phonenumber}, '==', true) .startAfter (last) .limit (3) .get ()

, тогда я получаю следующую ошибку:

[Info] 11-10 21:38:42.631 21908 21967 I ReactNativeJS: 'Error getting documents', { [Error: Firestore: Client specified an invalid argument. (firestore/invalid-argument).]

1 Ответ

0 голосов
/ 10 ноября 2019

Это ошибка в библиотеке react-native-firebase. Проверьте проблему на Github , чтобы следить за ней. Теперь проблема помечена как исправленная, и это исправление будет включено в следующую версию (> 5.5.6).


Старый ответ ниже ...


документ, который вы передаете в startAfter, должен содержать все, что нужно Firestore, чтобы определить, с чего начать дальше. Если поля, по которым вы фильтруете, не являются уникальными в коллекции, DocumentSnapshot также должен будет содержать идентификатор документа. Если ваш запрос показывает первый или второй документ, соответствующий критериям, а не тот, который находится после того, который вы ищете, скорее всего, потому что идентификатор отсутствует в lastDocument.


Послеваше обновление, я попытался воспроизвести проблему с помощью этого кода:

var db = firebase.firestore();
var ref = db.collection("58783480").orderBy('number', 'desc');
ref.get().then(function(snapshot) {
  console.log("Got all results");
  snapshot.forEach(function(doc) {
    console.log(doc.id+' => '+JSON.stringify(doc.data()));
  });  
  var last;
  ref.limit(2).get().then(function(snapshot) {
    console.log("Got first page");
    snapshot.forEach(function(doc) {
      console.log(doc.id+' => '+JSON.stringify(doc.data()));
      last = doc;
    });
    ref.startAfter(last).limit(2).get().then(function(snapshot) {
      console.log("Got second page");
      snapshot.forEach(function(doc) {
        console.log(doc.id+' => '+JSON.stringify(doc.data()));
        last = doc;
      });
    });
  })
});

живой пример здесь

Но вывод точно соответствует тому, что яожидал:

Получил все результаты

wbXwyLJheRfYXXWlY46j => {"index": 2, "number": 2}

kGC5cYPN1nKnZCcAb9oQ => {"index": 6," number ": 2}

8Ek8iWCDQPPJ5s2n8PiQ => {" index ": 4," number ": 2}

mr7MdAygvuheF6AUtWma => {" index ": 1," number": 1}

RCO5SvNn4fdoE49OKrIV => {" index ": 3," number ": 1}

CvVG7VP1hXTtcfdUaeNl => {" index ": 5," number ": 1}

Получил первую страницу

wbXwyLJheRfYXXWlY46j => {"index": 2, "number": 2}

kGC5cYPN1nKnZCcAb9oQ => {"index": 6, "number": 2}

Есть вторая страница

8Ek8iWCDQPPJ5s2n8PiQ => {"вdex ": 4," number ": 2}

mr7MdAygvuheF6AUtWma => {" index ": 1," number ": 1}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...