My messages disappear I get a new message or send messages

I’ve been facing this problem.

My code now disappears when get a new message. I want to make messages pile up, but I have tried many ways, but I have not solved them. I would really appreciate it if you could tell me how to do this.

When I enter a message room, I get 25 messages from firebase server. If there are more than 25 messages, last message disappears. Disappear message. I don’t want to like this …. enter image description here enter image description here

I want to like this.

here is my disappear code

const messageLimit = 25;
  const [messagesSnapshot] = useCollection(
    db
      .collection('chats')
      .doc(id)
      ?.collection('messages')
      .orderBy('timestamp', 'desc')
      .limit(messageLimit),
  );
    if (messagesSnapshot) {
      const snap = messagesSnapshot.docs;
      const startPost = messagesSnapshot.docs[messagesSnapshot.docs.length - 1];
      setStartAt(startPost);
      const messages = snap.map(message => ({
        id: message.id,
        user: message.data().user,
        messageInfo: {
          ...message.data(),
          timestamp: message.data().timestamp?.toDate().getTime(),
        },
      }));
      setMessagesList(messages);
    }
  const getMoreMessages = async () => {
    if (!lastPost) {
      setIsGetMessagesLoading(true);
      const query = await db
        .collection('chats')
        .doc(id)
        .collection('messages')
        .orderBy('timestamp', 'desc')
        .startAfter(startAt)
        .limit(messageLimit)
        .get();
      const messages = query.docs.map(message => ({
        id: message.id,
        user: message.data().user,
        messageInfo: {
          ...message.data(),
          timestamp: message.data().timestamp?.toDate().getTime(),
        },
      }));
      setStartAt(query.docs[query.docs.length - 1]);
      setMessagesList([...messagesList, ...messages]);
      setIsGetMessagesLoading(false);
      messages.length === 0 ? setLastPost(true) : setLastPost(false);
    }
  };
  useEffect(() => {
    showMessages();
  }, [messagesSnapshot]);

Answer

As Shyam commented, you’ve limited the query to 25 messages, so when a new message is added, the oldest message falls out of the query.

One thing you could do is detect the changes between the updates, and never remove the “outdated” documents.

The example from the documentation:

db.collection("cities").where("state", "==", "CA")
    .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
            if (change.type === "added") {
                console.log("New city: ", change.doc.data());
            }
            if (change.type === "modified") {
                console.log("Modified city: ", change.doc.data());
            }
            if (change.type === "removed") {
                console.log("Removed city: ", change.doc.data());
            }
        });
    });

So you’d only handled added (which is initially every document) and possibly modified, but ignore removed.