У меня есть документ, в котором есть массив комментариев объектов, и каждый объект имеет свойство createdAt. Я хочу отсортировать все комментарии, которые находятся внутри массива комментариев, используя свойство createdAt, поэтому новый комментарий будет вверху.
Я провел некоторое исследование и обнаружил, что мы можем сделать это в база данных Firebase в реальном времени, но я хочу упорядочить данные с помощью firestore.
Вот мой код:
import { useEffect, useRef, useState } from "react"
// firebase import
import { doc, onSnapshot, orderBy, query } from "firebase/firestore"
import { db } from "../firebase/config"
export const useDocument = (c, id, o) => {
const [document, setDocument] = useState(null)
const [error, setError] = useState(null)
// realtime document data
useEffect(() => {
let docRef = doc(db, c, id)
if (o) {
docRef = query(docRef, orderBy("createdAt", "desc")) // this is not working
}
const unsubscribe = onSnapshot(
docRef,
(snapshot) => {
// need to make sure the doc exists & has data
if (snapshot.data()) {
setDocument({ ...snapshot.data(), id: snapshot.id })
setError(null)
} else {
setError("No such document exists")
}
},
(err) => {
console.info(err.message)
setError("failed to get document")
}
)
// unsubscribe on unmount
return () => unsubscribe()
}, [c, id])
return { document, error }
}
«У меня есть документ, в котором есть массив комментариев объектов, и каждый объект имеет свойство createdAt». -> означает ли это, что ваши комментарии не являются документами в (под) коллекции, а являются полем в одном документе?
да! У меня есть комментарии как поле (массив объектов комментариев) в документе, это не отдельный документ или подколлекция.
Функция query()
принимает в качестве параметра запрос, а не DocumentReference. Также предложение документы заказовorderBy()
при выборке нескольких документов из коллекции, а не элементов массива.
Чтобы упорядочить элементы массива, вам сначала нужно получить этот документ, а затем вручную отсортировать массив.
const unsubscribe = onSnapshot(
docRef,
(snapshot) => {
// need to make sure the doc exists & has data
if (snapshot.data()) {
const orderedArray = snapshot.data().comments.sort((a, b) => a.createdAt.seconds - b.createdAt.seconds);
} else {
setError("No such document exists")
}
}
)
Я получаю это сообщение об ошибке TypeError: a.createdAt.getTime is not a function
@ r007 вы уверены, что поле createdAt
присутствует во всех элементах массива? Попробуйте использовать a.createdAt?.getTime()
да! У меня есть поле createdAt
во всех элементах массива. Я также пробовал это ?.
, но все равно получил ту же ошибку. Я приложил скриншот объекта createdAt
, пожалуйста, проверьте.
@ r007 да, это Временная метка пожарного магазина, я это пропустил. Попробуйте a.createdAt.seconds - b.createdAt.seconds
Почему вы используете
doc()
? Doc ссылается на один документ, возвращая DocumentReference. Итак, вашsnapshot.size
равен 1 - заказывать нечего. Заказ CollectionReference вquery
будет работать, как и ожидалось.