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