본문 바로가기

카테고리 없음

WelKo_개선 ( 채팅 )

supabase에서 realtime 적용이 필요한 테이블에만 설정

 

 

export const fetchMessages = async (senderId: string, receiverId: string, postId: string) => {
  const { data, error } = await supabase
    .from('messages')
    .select(
      `
      *,
      sender:users!messages_sender_id_fkey ( id, name, avatar ),
      receiver:users!messages_receiver_id_fkey ( id, name, avatar )
    `
    )
    .eq('post_id', postId)
    .or(
      `and(sender_id.eq.${senderId},receiver_id.eq.${receiverId}),and(sender_id.eq.${receiverId},receiver_id.eq.${senderId})`
    )
    .order('created_at', { ascending: true });

  if (error) {
    return [];
  }

  const uncheckedMessages = data.filter((message) => message.receiver_id === receiverId && !message.is_checked);
  if (uncheckedMessages.length > 0) {
    const uncheckedMessageIds = uncheckedMessages.map((message) => message.id);
    await supabase.from('messages').update({ is_checked: true }).in('id', uncheckedMessageIds);
  }

  // Realtime 구독 설정
  supabase
    .channel('public:messages')
    .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) => {
      if (
        payload.new.post_id === postId &&
        (payload.new.sender_id === senderId || payload.new.receiver_id === receiverId)
      ) {
        // 새로운 메시지를 처리하는 로직을 추가
        data.push(payload.new); // 실시간으로 수신된 메시지를 기존 데이터에 추가
      }
    })
    .subscribe();

  return data;
};

기존 코드에서 realtime 구독 코드를 추가하여 채팅 리스트 및 채팅 내역을 불러 올 시 기존에 사용하던 Interval을 사용하지 않아도 최신화 되도록 개선

 

  // useEffect(() => {
  //   if (chatData.length > 0 && !intervalId) {
  //     const id = setInterval(() => {
  //       queryClient.invalidateQueries({
  //         queryKey: ['chatList', userId]
  //       });
  //     }, 1000);
  //     setIntervalId(id);
  //   }

  //   return () => {
  //     if (intervalId) clearInterval(intervalId);
  //   };
  // }, [chatData, queryClient, userId, intervalId]);

기존에 사용하던 채팅 리스트 인터벌 코드를

  useEffect(() => {
    const loadMessages = async () => {
      await fetchMessages(userId, userId, ''); // 초기 데이터 로드
    };

    loadMessages();

    const channel = supabase
      .channel('public:messages')
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) => {
        if (payload.new.post_id && (payload.new.sender_id === userId || payload.new.receiver_id === userId)) {
          queryClient.invalidateQueries({ queryKey: ['chatList', userId] });
        }
      })
      .subscribe();

    return () => {
      // 컴포넌트 언마운트 시 구독 취소
      channel.unsubscribe();
    };
  }, [userId, queryClient]);

위와 같이 리얼타임 기능을 통해 변경된 테이블 내용을 다시 불러오도록 변경

-> 하지만 전체 내역을 다시 불러와서 비효율 발생하여 개선 필요

  // useEffect(() => {
  //   const fetchData = async () => {
  //     const fetchedMessages = await fetchMessages(senderId, receiverId, postId);
  //     setMessages(fetchedMessages);
  //   };

  //   const interval = setInterval(fetchData, 1000);
  //   return () => clearInterval(interval);
  // }, [senderId, receiverId, postId]);

기존에 사용하던 채팅 내역 인터벌 코드를

  useEffect(() => {
    const loadMessages = async () => {
      const fetchedMessages = await fetchMessages(senderId, receiverId, postId);
      setMessages(fetchedMessages);
    };

    loadMessages();
  }, [senderId, receiverId, postId]);

위와 같이 초기에 대화 내역을 불러오도록 useEffect 사용하도록 개선