Advertisements
I have a document in which there is a comments array of objects and each object has createdAt property. I want to sort all the comments that are inside the comments array using the createdAt property, so, a new comment comes to the top.
I did some research and found that we can do this in firebase’s real-time database but I want to do the ordering of data using firestore.
Here is my code:
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.log(err.message)
setError("failed to get document")
}
)
// unsubscribe on unmount
return () => unsubscribe()
}, [c, id])
return { document, error }
}
>Solution :
The query()
function takes a query as parameter and not a DocumentReference. Also the orderBy()
clause orders documents when fetching multiple documents from a collection and not array elements.
To order array elements, you first need to fetch that document and then manually sort the array.
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.getTime() - b.createdAt.getTime());
} else {
setError("No such document exists")
}
}
)