최종 프로젝트 - supabase 실시간 챝

Rock Kyun·2024년 1월 9일
1

오늘 했던 것

  • 기능에 필요한 테이블 설정
  • 실시간 채팅 구현

테이블 설정

  • 구글에 검색을 해본 뒤 일반적으로 실시간 채팅에 사용하는
    테이블 구성을 참고하여 작성했다.
    유저 테이블, 메세지 테이블, 채팅방 테이블

메세지 - 채팅방 - 유저 테이블을 어떻게 연결하고 참조하지..?

  • 답은 foreign key였다.
    채팅방의 room_id를 foreign key로 참조하여 메세지를 가져와
    이 메세지 데이터가 어느 채팅방에 소속 된 데이터인지 알게 되는 것.
    유저도 어느 채팅방에 소속되었는지 foreign key로 연결할 수 있었다.

1차 테스트 - 혼자 쓰는 채팅 (성공)

  • 연결된 테이블을 실시간으로 구독하는 것을 이해하기 위해
    로그인 된 유저가 혼자 쓰는 채팅방을 만들어봤다.
  • 채팅 시작 버튼을 누르면 채팅방(input만 달랑 있는 방)으로 들어가
    인풋에 메세지를 작성해 보내면 실시간으로 추가되는 데이터가 오고
    state에 업데이트 해서 실시간으로 나오도록 하였다.

로직은 간단했다


 // 컴포넌트 마운트 시 메세지 가져오기
 const getMsg = async () => {
    try {
      let { data: chat_messages, error } = await supabase
        .from("chat_messages")
        .select("*");
      // 메세지 가져온 것을 state에 업데이트 하기
      setTestOne(chat_messages);
    } catch (err) {
      console.log(err);
    }
  };

  // 채팅메세지 테이블을 구독하여 모든 이벤트에 대한 알림을 받도록 하는 함수
  useEffect(() => {
    const updatedMessages = supabase
      .channel("custom-all-channel")
      .on(
        "postgres_changes",
        { event: "*", schema: "public", table: "chat_messages" },
        (payload) => {
          setTestOne((prev) => [...prev, payload.new]);
        }
      )
      .subscribe();

    // 마운트 시 메세지 가져오기
    getMsg();

    // 언마운트 시 구독 해제
    return () => {
      updatedMessages.unsubscribe();
    };
  }, []);

해결하지 못한 문제

  1. 테스트 유저 계정 2개를 만들었다.
  2. 회원가입 시 유저 테이블에 정해둔 scheme 형태의 유저 데이터가
    user 테이블에 업데이트 된다.
  3. 한 유저로 로그인 하여 다른 유저에게 채팅하기 버튼을 클릭 시
    클릭 된 유저의 uid와 클릭한 유저의 uid를 가진 채팅방 테이블이 생성된다.
  4. 채팅방으로 이동하면 현재 로그인 된 유저가 소속된 채팅방을 모두 가져온다.

현재 이 4번에 막혀있다.

const { data: chatRooms, error } = await supabase
        .from("chat_room")
        .select()
        .contains("participants", [{ user_id: userData.id }]);

이렇게 participants 필드에서 user_id가 현재 로그인 유저 id와 같은 것을
가져오도록 쿼리를 작성했는데
JSON 타입에 유효하지 않은 input 문법 오류(?)가 나온다..
아무래도 테이블 설정을 잘못한 것이거나 쿼리문의 오류겠지.. 하는 막연한 생각이 든다.

오늘 강의를 한번 더 듣고 놓친 부분을 확인해봐야겠다..

0개의 댓글