最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to order documents in a collection in Firestore - Stack Overflow

programmeradmin5浏览0评论

I have a problem, after the version 9 update of Firebase, I cant seem to figure out how to order the documents in a collection.

Here is my code. I do not seem to understand how to implement the orderBy in the onSnapshot. Can someone please nudge me in the right direction. I have looked through the documentation but could not find a solution.

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;

I have a problem, after the version 9 update of Firebase, I cant seem to figure out how to order the documents in a collection.

Here is my code. I do not seem to understand how to implement the orderBy in the onSnapshot. Can someone please nudge me in the right direction. I have looked through the documentation but could not find a solution.

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;
Share Improve this question edited Sep 22, 2021 at 12:34 Renaud Tarnec 83.2k10 gold badges98 silver badges129 bronze badges Recognized by Google Cloud Collective asked Sep 22, 2021 at 11:21 Franco LabuschagneFranco Labuschagne 891 silver badge8 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 5

Okay, I found a solution:

When you use the order by, if the field you are trying to order the documents by does not excist in the document, the order by will not "store" and order that document. Next, in my chat application I created a field with the Timestamp constructor that Firebase offers. That allowed me to order the documents in the createdAt order.

My code for the ChatBox file: 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()));
    });
  }, []);

SendMessage.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()),
    });
  }

Hope this makes sense.

In JS API v9 we have to perform everything in a functional way. To order the collection before you attach a listener, you need to perform a query. A query can take a reference, order the results and pass the results to the caller.

In other words, your code should look like this:

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()));
    });
  }, []);

Change YOUR_FIELD with the reference to any field you want to use to order the results. What we are doing here is:

  • getting a reference to a collection
  • asking firestore to perform a query on that collection, ordering the results by a field
  • attaching a listener to the results

Hi can you can try this :

useEffect(() => {
    onSnapshot(query(collection(db, "messages").orderBy('createdAt').startAfter(today)), 
      (snapshot) => {
      setMessages(snapshot.docs.map((doc) => doc.data()));
    }); 
    }, []);
发布评论

评论列表(0)

  1. 暂无评论