Как заказать документы в коллекции в Firestore

# #javascript #reactjs #firebase #google-cloud-firestore

Вопрос:

У меня проблема, после обновления Firebase версии 9 я не могу понять, как упорядочить документы в коллекции.

Вот мой код. Я, кажется, не понимаю, как реализовать OrderBy в onSnapshot. Может кто-нибудь, пожалуйста, подтолкнуть меня в правильном направлении. Я просмотрел документацию, но не смог найти решения.

 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;
 

Ответ №1:

Ладно, я нашел решение:

Когда вы используете заказ по, если поле, по которому вы пытаетесь заказать документы, не указано в документе, заказ по не будет «хранить» и заказывать этот документ. Затем в моем приложении для чата я создал поле с Timestamp конструктором, который предлагает Firebase. Это позволило мне заказать документы в createdAt порядке.

Мой код для файла чата: 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()),
    });
  }
 

Надеюсь, в этом есть смысл.

Ответ №2:

В JS API v9 мы должны выполнять все функционально. Чтобы упорядочить коллекцию перед подключением прослушивателя, вам необходимо выполнить запрос. Запрос может взять ссылку, упорядочить результаты и передать результаты вызывающему.

Другими словами, ваш код должен выглядеть следующим образом:

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

Измените YOUR_FIELD со ссылкой на любое поле, которое вы хотите использовать для упорядочения результатов.
То, что мы здесь делаем, это:

  • получение ссылки на коллекцию
  • попросите firestore выполнить запрос к этой коллекции, упорядочив результаты по полю
  • прикрепление прослушивателя к результатам

Комментарии:

1. Привет, я пробовал делать это таким образом, но при запуске на моей странице ничего не отображается. Я не получаю ошибок, но кажется, что массив пуст, если я сделаю это таким образом? Никаких мыслей.

Ответ №3:

Привет, ты можешь попробовать это :

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

Комментарии:

1. Это синтаксис v8. В версии 9 в CollectionReference больше нет метода OrderBy и множества других методов, поскольку API был изменен, чтобы стать функциональным API

2. Я вас понимаю , поэтому попробуйте добавить запрос к этой коллекции, чтобы получить ответ

3. Юп, это не работает с v9