Vue3, Firebase 프로젝트 - 채팅앱 VSignal

14. Vue3 Firebase 프로젝트 채팅앱 VSignal - 안 읽은 메시지 개수 배지 추가하기

그랜파 개발자 2025. 3. 25. 06:23

🔥 안 읽은 메시지 개수 배지 추가하기

채팅방별 안 읽은 메시지 개수 Firebase에서 실시간으로 가져와서
안 읽은 메시지가 있는 채팅방에 배지(🔴) 표시하고
새 메시지가 오면 UI 자동 업데이트하여
채팅방 목록에서 각 채팅방의 안 읽은 메시지 개수 표시할 수 있습니다.

 

1. 안 읽은 메시지 개수 계산

채팅방 목록에서 각 채팅방의 안 읽은 메시지 개수 표시
Firebase에서 실시간으로 가져와 UI 업데이트

2. Store에서 안 읽은 메시지 개수 관리

📌 store/chatStore.js 수정

import { defineStore } from "pinia";
import { getDatabase, ref, onValue } from "firebase/database";
import { auth } from "@/firebase";

export const useChatStore = defineStore("chat", {
  state: () => ({
    chatRooms: [], // 🔥 채팅방 목록 저장
    unreadCounts: {}, // 🔥 채팅방별 안 읽은 메시지 개수 저장
  }),

  actions: {
    // ✅ 모든 채팅방 가져오기
    fetchChatRooms() {
      const db = getDatabase();
      const user = auth.currentUser;
      if (!user) return;

      const chatRoomsRef = ref(db, `users/${user.uid}/chatRooms`);
      onValue(chatRoomsRef, (snapshot) => {
        if (snapshot.exists()) {
          this.chatRooms = Object.entries(snapshot.val()).map(([id, room]) => ({
            id,
            ...room,
          }));
          // 🔥 채팅방 가져온 후 안 읽은 메시지 개수 업데이트
          this.listenForUnreadMessages(); 
        }
      });
    },

    // ✅ 채팅방별 안 읽은 메시지 개수 계산
    listenForUnreadMessages() {
      const db = getDatabase();
      const user = auth.currentUser;
      if (!user) return;

      this.chatRooms.forEach((room) => {
        const messagesRef = ref(db, `messages/${room.id}`);

        onValue(messagesRef, (snapshot) => {
          if (snapshot.exists()) {
            const unreadMessages = Object.values(snapshot.val()).filter(
              (msg) => msg.receiver === user.uid && msg.status === "unread"
            );
            // 🔥 안 읽은 메시지 개수 업데이트
            this.unreadCounts[room.id] = unreadMessages.length; 
          } else {
            this.unreadCounts[room.id] = 0;
          }
        });
      });
    },
  },
});

✔ 채팅방 목록 불러오기 (fetchChatRooms())
✔ 각 채팅방의 안 읽은 메시지 개수 실시간 업데이트 (listenForUnreadMessages())

3. UI에서 안 읽은 메시지 개수 표시

📌 ChatList.vue 수정 (채팅방 목록 UI)

<script setup>
import { useChatStore } from "@/store/chatStore";
import { onMounted } from "vue";

const chatStore = useChatStore();

onMounted(() => {
  chatStore.fetchChatRooms(); // 🔥 채팅방 목록 가져오기
});
</script>

<template>
  <v-list>
    <v-list-item
      v-for="chatRoom in chatStore.chatRooms"
      :key="chatRoom.id"
      :to="`/chat/${chatRoom.id}`"
    >
      <v-list-item-content>
        <v-list-item-title>{{ chatRoom.name }}</v-list-item-title>
      </v-list-item-content>

      <!-- ✅ 안 읽은 메시지가 있으면 배지 표시 -->
      <v-badge
        v-if="chatStore.unreadCounts[chatRoom.id] > 0"
        :content="chatStore.unreadCounts[chatRoom.id]"
        color="red"
      >
        <v-icon>mdi-message</v-icon>
      </v-badge>
    </v-list-item>
  </v-list>
</template>

✔ 안 읽은 메시지가 있을 때만 빨간 배지 표시
✔ 채팅방에 새 메시지가 오면 배지 숫자 실시간 업데이트

🎯 결론

✅ 채팅방별 안 읽은 메시지 개수 Firebase에서 실시간으로 가져옴
✅ 안 읽은 메시지가 있는 채팅방에 배지(🔴) 표시
✅ 새 메시지가 오면 UI 자동 업데이트 🚀