How can I render only the last message of chat locally, with animation in react native?

I have a chat app and it fetches all the messages from Firestore when user opens a chat window at the first run with useEffect(), but when a new message is getting sent by the user it must get added to local state for better user experience with local timeStamp with a fade-in animation instead of back and fort from database, , right now it works fine but for some reason the sent messages gets displayed and gets removed very quickly and gets displayed again. I feel like it’s fetching from the database instead of locally. how can I make this work?

“`

const NewChatSection = ({ navigation, route }) => {
  const [messages, setMessages] = useState([]);
  const [message, setMessage] = useState("");
  const [lastMessage, setdddLastMessage] = useState(null);
  const scrollViewRef = useRef();
  const db = getFirestore();
  const auth = FIREBASE_AUTH;
  const { uid, displayName } = route.params;
  const userUIDs = [auth.currentUser.uid, uid].sort();
  const chatId = userUIDs.join("-");
  const chatRef = doc(db, "chats", chatId);
  const messagesRef = collection(db, "chats", chatId, "messages");
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const fadeIn = () => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 500,
      useNativeDriver: true,
    }).start();
  };

  if (Platform.OS === "android") {
    if (UIManager.setLayoutAnimationEnabledExperimental) {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }
  }

  const handleSend = async () => {
    if (message.trim() === "") {
      return;
    }

    const newMessage = {
      text: message,
      timestamp: new Date(), // This timestamp is for local display purposes only
      senderName: auth.currentUser.displayName,
      senderId: auth.currentUser.uid,
      receiverId: uid,
      receiverName: displayName,
      type: "sentMessage",
    };

    const newMessageForDb = {
      ...newMessage,
      timestamp: serverTimestamp(), // Use serverTimestamp for the database
    };

    // Optimistically update the local state with the new message
    setMessages((prevMessages) => [...prevMessages, newMessage]);

    try {
      await addDoc(messagesRef, newMessageForDb);
      setMessage("");
      fadeIn(); // Trigger the animation for the local message
    } catch (error) {
      console.error("Error sending message: ", error);
    }
  };

  useEffect(() => {
    const receiverUID = route.params?.uid;
    const currentUserUID = auth.currentUser.uid;
    const userUIDs = [currentUserUID, receiverUID].sort();
    const chatId = userUIDs.join("-");
    const messagesRef = collection(db, "chats", chatId, "messages");
    const q = query(messagesRef, orderBy("timestamp"));

    const unsubscribe = onSnapshot(q, (querySnapshot) => {
      const fetchedMessages = querySnapshot.docs.map((doc) => {
        let msg = doc.data();
        msg.type =
          msg.senderId === auth.currentUser.uid
            ? "sentMessage"
            : "receivedMessage";
        return msg;
      });
      setMessages(fetchedMessages);
      if (fetchedMessages.length > 0) {
        const lastMessage = fetchedMessages[fetchedMessages.length - 1];
        const users = {
          participants: [auth.currentUser.uid, uid].sort(),
          senderName: auth.currentUser.displayName,
          receiverName: displayName,
          lastMessage: lastMessage.text,
          lastMessageTimestamp: lastMessage.timestamp,
          deleted: false,
        };
        setDoc(chatRef, users, { merge: true });
      }
    });

    return () => unsubscribe();
  }, []);

  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === "ios" ? "padding" : "height"}
      style={styles.container}
      // animationType="slide"
    >
      <SafeAreaView style={styles.safeAreaContainer}>
        <View style={styles.header}>
          <TouchableOpacity
            onPress={() => navigation.goBack()}
            style={styles.closeButton}
          >
            <Svg
              xmlns="http://www.w3.org/2000/svg"
              fill="none"
              viewBox="0 0 24 24"
              stroke="#FFFFFF"
              width={30}
              height={30}
            >
              <Path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M15 19l-7-7 7-7"
              />
            </Svg>
          </TouchableOpacity>
          <Text style={styles.title}>{displayName}</Text>
        </View>
        <ScrollView
          style={styles.scrollViewContent}
          keyboardShouldPersistTaps="handled"
          ref={scrollViewRef}
          onContentSizeChange={() => {
            scrollViewRef.current.scrollToEnd({ animated: true });
          }}
        >
          {Array.isArray(messages) &&
            messages.map(
              (msg, index) => (
                console.log("MESSAGE: ", msg),
                (
                  <View
                    key={index}
                    style={[
                      msg.type === "sentMessage"
                        ? styles.messageContainer
                        : styles.messageContainerReceived,
                      {
                        flexDirection: "row",
                        justifyContent: "space-between",
                        alignItems: "center",
                      },
                    ]}
                  >
                    <Text style={styles.messageText}>{msg.text}</Text>
                    {msg.timestamp && (
                      <Text style={styles.messageTimestamp}>
                        {format(
                          msg.timestamp instanceof Date
                            ? msg.timestamp
                            : msg.timestamp.toDate(),
                          "p"
                        )}
                      </Text>
                    )}
                  </View>
                )
              )
            )}
/////////////////////////////////////COMMENTED OUT
          {/* {lastMessage && (
            <Animated.View
              style={[
                { opacity: fadeAnim },
                lastMessage.type === "sentMessage"
                  ? styles.messageContainer
                  : styles.messageContainerReceived,
                {
                  flexDirection: "row",
                  justifyContent: "space-between",
                  alignItems: "center",
                },
              ]}
            >
              <Text style={styles.messageText}>{lastMessage.text}</Text>
              <Text style={styles.messageTimestamp}>
                {format(new Date(), "p")}
              </Text>
            </Animated.View>
          )} */}
/////////////////////////////////COMMENTED OUT
        </ScrollView>

        <View style={styles.inputContainer}>
          <TextInput
            placeholder="Type your message..."
            style={styles.input}
            multiline
            value={message}
            onChangeText={setMessage}
            placeholderTextColor={"#ccc"}
          />

          <TouchableOpacity onPress={handleSend} style={styles.sendButton}>
            <Icon name="send" size={22} color="white" />
          </TouchableOpacity>
        </View>
      </SafeAreaView>
    </KeyboardAvoidingView>
  );
};

“`

I tried separating all the messages from the last message, but it didn’t work and it was making it super complicated, maybe the time is getting said twice, but after the first render everything else that’s happening on the screen must get done locally.