Tengo un problema, después de la actualización de la versión 9 de Firebase, parece que no puedo averiguar cómo ordenar los documentos en una colección.
Aquí está mi código. Parece que no entiendo cómo implementar orderBy en onSnapshot. ¿Alguien puede empujarme en la dirección correcta? He revisado la documentación pero no he podido encontrar una solución.
import React, { useState, useEffect } from "react"; import SignOut from "./SignOut"; import { Grid, Typography, Avatar } from "@material-ui/core"; import db from "../firebase"; import { onSnapshot, collection, orderBy, query, limit } from "firebase/firestore"; import SendMessage from "./SendMessage"; function ChatBox() { const [messages, setMessages] = useState([]); useEffect(() => { onSnapshot(collection(db, "messages"), (snapshot) => { setMessages(snapshot.docs.map((doc) => doc.data())); }); }, []); return ( <> <Grid container> <Grid item xs="12" style={{ textAlign: "right" }}> <SignOut></SignOut> </Grid> {messages.map(({ id, text, photoURL }) => ( <Grid item xs="12" key={id} style={{ marginBottom: "1rem" }}> <Avatar alt="" src={photoURL} /> <Typography>{text}</Typography> </Grid> ))} </Grid> <Grid container> <SendMessage></SendMessage> </Grid> </> ); } export default ChatBox;
Bien, encontré una solución:
Cuando utiliza el orden por, si el campo por el que intenta ordenar los documentos no existe en el documento, el orden por no "almacenará" ni ordenará ese documento. Luego, en mi aplicación de chat, creé un campo con el constructor Timestamp
que ofrece Firebase. Eso me permitió ordenar los documentos en el orden createdAt
.
Mi código para el archivo ChatBox: Chatbox.js
import { collection, query, onSnapshot, orderBy } from "firebase/firestore"; //OTHER CODE useEffect(() => { onSnapshot(query(collection(db, "messages"), orderBy("createdAt")), (snapshot) => { setMessages(snapshot.docs.map((doc) => doc.data())); }); }, []);
EnviarMensaje.js
import { collection, addDoc, Timestamp } from "firebase/firestore"; //OTHER CODE const [userMessage, setUserMessage] = useState(""); async function sendUserMessage(e) { const auth = getAuth(); e.preventDefault(); const { uid, photoURL } = auth.currentUser; await addDoc(collection(db, "messages"), { text: userMessage, photoURL, uid, createdAt: Timestamp.fromDate(new Date()), }); }
Espero que esto tenga sentido.
En JS API v9 tenemos que realizar todo de manera funcional. Para ordenar la colección antes de adjuntar un oyente, debe realizar una consulta. Una consulta puede tomar una referencia, ordenar los resultados y pasar los resultados a la persona que llama.
En otras palabras, su código debería verse así:
import { onSnapshot, collection, orderBy, query, limit } from "firebase/firestore"; //OTHER CODE useEffect(() => { onSnapshot(query(collection(db, "messages"), orderBy("YOUR_FIELD")), (snapshot) => { setMessages(snapshot.docs.map((doc) => doc.data())); }); }, []);
Cambie YOUR_FIELD con la referencia a cualquier campo que desee usar para ordenar los resultados. Lo que estamos haciendo aquí es:
Hola, puedes probar esto:
useEffect(() => { onSnapshot(query(collection(db, "messages").orderBy('createdAt').startAfter(today)), (snapshot) => { setMessages(snapshot.docs.map((doc) => doc.data())); }); }, []);