Разбивка на страницы Firebase с использованием метки времени / даты в качестве упорядочения

#reactjs #firebase #google-cloud-firestore

#reactjs #firebase #google-облако-firestore

Вопрос:

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

Это в основном то, что я делаю:

 let jobsRef = db.collection("jobs")
            .orderBy('createdAt', 'desc')
            .limit(QUERY_LIMIT);
jobsRef = jobsRef.startAfter(this.props.jobs[this.props.jobs.length - 1].createdAt);
  

Однако кажется, что иногда я получаю возвращенные элементы, которые я только что получил. Я предполагаю, что из-за похожих дат?
Итак, как я мог бы в принципе вернуть список заданий, упорядоченных по createdAt, и иметь смещение / ограничение (нумерацию страниц)?

createdAt выглядит как тип метки времени: 23 October 2020 at 17:26:31 UTC 2 когда я регистрирую createdAt, однако я вижу это: {seconds: 1603537477, nanoseconds: 411000000} может быть, мне следует сохранить createdAt как временную метку unix? Или каков идеальный способ справиться с этим?

Вот как это выглядит в базе данных (всплывающее окно, когда я нажимаю редактировать на createdAt): введите описание изображения здесь

Ответ №1:

Если несколько документов могут иметь одинаковое значение для поля, по которому вы сортируете, передача значения для этого поля не гарантирует, что оно укажет на уникальный документ. Таким образом, вы действительно можете передавать неоднозначную инструкцию, что приводит к нежелательному результату.

Когда это возможно, я настоятельно рекомендую передавать весь документ в Firestore API. Это позволяет Firestore извлекать необходимые данные из этого документа, чтобы однозначно / однозначно найти привязку для вашего запроса.

Поэтому вместо:

 jobsRef.startAfter(this.props.jobs[this.props.jobs.length - 1].createdAt);
  

Выполните:

 jobsRef.startAfter(this.props.jobs[this.props.jobs.length - 1]);
  

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

1. Дело в том, что это this.props.jobs[this.props.jobs.length - 1] возвращает не объект firebase, а стандартный js-объект моей работы. Я делаю это, потому что я использую NextJS, и когда я пытаюсь вернуть объект firebase в getInitialProps(), я получаю некоторую проблему с циклической структурой. (не уверен, насколько вы знакомы с NextJS)

2. Это действительно проблема. Я рекомендую сохранить DocumentSnapshot и передать это. Если это невозможно, попробуйте упорядочить по / и передать идентификатор документа в качестве дополнительного условия, чтобы его можно было использовать для устранения неоднозначности между документами.

3. Да, похоже, не отличается, и я не могу найти решение для передачи документа. Я думаю, я могу просто попробовать Date.now() сохранить временную метку unix, и, надеюсь, ее будет легко разбить на страницы

4. Timestamp Тип Firestore более точен, чем метка времени в миллисекундах Unix, так что это не должно делать его лучше. Но трудно быть уверенным, не видя фактических данных, как они инициализируются, как они выглядят в базе данных и как они отображаются в выводе вашего запроса, в вашем вопросе.

5. Поэтому, когда я использую createdAt, который является форматом типа метки времени unix, например, 1603558041210 тогда, он работает отлично! Я обновил вопрос изображением, каким был createdAt, прежде чем я изменил его на временную метку unix

Ответ №2:

Я столкнулся с аналогичной проблемой, после майских часов я, наконец, нашел решение, все, что вам нужно сделать, это преобразовать это число в метку времени firestore

 import { Timestamp }. from @angular/fire/firestore;


let createdAt: number = 56772766688383;

let timestamp = Timestamp.fromMillis(createdAt);

//then pass that to startAfter

startAfter(timestamp)