How to order comments in firebase firestore by createdAt

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 }
}

createdAt property: enter image description here

1 answer

  • answered 2022-05-07 06:30 Dharmaraj

    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.seconds - b.createdAt.seconds);
        } else {
          setError("No such document exists")
        }
      }
    )
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum