[TIL]240124_supabase를 이용한 알림기능

ㅇㅖㅈㅣ·2024년 1월 24일
0

Today I Learned

목록 보기
64/93
post-thumbnail

👩🏻‍💻 Today Learn

  • 기술면접 1:1
  • 실시간 알림기능 구현중

📚 작업내용

내가 등록한 상품에 누군가가 찜을 눌렀을 때 알림을 받을 수 있는 기능을 구현해보고 있다.

supabase의 Realtime을 이용해서 채널구독

 // Header
  useEffect(() => {
    if (!user) return;
    const subscription: RealtimeChannel = supabase
      .channel('alert-message-insert-channel')
      .on(
        'postgres_changes',
        {
          event: 'INSERT',
          schema: 'public',
          table: 'alert_message',
          filter: `user_id=eq.${user.id}`
        },
        (payload) => {
          const message = payload.new.message;
          alertBottomRight(message);
          queryClient.invalidateQueries({
            queryKey: [ALERT_MESSAGE_QUERY_LEY]
          });
        }
      )
      .subscribe();
    return () => {
      subscription.unsubscribe();
    };
  }, [user]);

supabase select, insert, update API

// alertMessage.ts
import { supabase } from '@/shared/supabase/supabase';
import { Tables } from '@/shared/supabase/types/supabase';

export type AlertType = {
  type: string;
  targetId: number;
  message: string;
  userId: string;
};

// alert_message 테이블에서 데이터 가져오기
export const findAllMessageByUserId = async (userId: string) => {
  const findAllMessageQuery = await supabase
    .from('alert_message')
    .select('*')
    .order('created_at', { ascending: false })
    .eq('user_id', userId)
    .returns<Tables<'alert_message'>[]>();

  const { data, error } = findAllMessageQuery;
  return { data, error };
};

// alert_message 테이블에 데이터 넣기
export const addAlertMessageByIdAndTarget = async ({
  type,
  targetId,
  message,
  userId
}: AlertType) => {
  await supabase
    .from('alert_message')
    .insert({ type, message, target_id: targetId, user_id: userId })
    .select();
};

// 알림 메시지 클릭 시 읽음상태로 만들기
export const updateAlertMessageStatus = async (id: string) => {
  return await supabase.from('alert_message').update({ status: true }).eq('id', id);
};

쿼리로 데이터 가져오고 추가하고 업데이트 하는 훅

// useAlertMessage.ts
import {
  AlertType,
  addAlertMessageByIdAndTarget,
  findAllMessageByUserId,
  updateAlertMessageStatus
} from '@/apis/alertMessage';
import { QueryClient, useMutation, useQuery } from '@tanstack/react-query';
import useAuth from './useAuth';

export const ALERT_MESSAGE_QUERY_LEY = 'alert_message';
const queryClient = new QueryClient();

export const useAlertMessage = () => {
  const user = useAuth((state) => state.user);

  const { data: fetchAlertMessage } = useQuery({
    queryKey: [ALERT_MESSAGE_QUERY_LEY],
    queryFn: () => findAllMessageByUserId(user!.id),
    // 유저가 있을때만 실행하도록
    enabled: !!user
  });

  const { mutate: addAlertMessage } = useMutation({
    mutationFn: async (message: AlertType) => await addAlertMessageByIdAndTarget(message),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [ALERT_MESSAGE_QUERY_LEY] });
    }
  });

  const { mutate: updateAlertMessage } = useMutation({
    mutationFn: async (id: string) => await updateAlertMessageStatus(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [ALERT_MESSAGE_QUERY_LEY] });
    }
  });

  return {
    fetchAlertMessage,
    addAlertMessage,
    updateAlertMessage
  };
};

✍🏻 회고

오류도 많이 발생하고 원리가 머릿속으로 바로 그려지지 않아서 생각보다 많이 더디고 오래걸리고 있다ㅜ
오늘은 꼭 구현해야지..!

profile
웰씽킹_나는 경쟁력을 갖춘 FE개발자로 성장할 것이다.

0개의 댓글