최종 프로젝트-실시간 채팅 이미지 전송

Rock Kyun·2024년 1월 14일
1

오늘 했던 것

  • 실시간 채팅 이미지 전송 기능

접근 방식

  • Supabase의 Storage와 연계하여 작업하는 거라서
    처음에는 감이 오지 않았지만,
    데이터를 다루는 흐름을 파악한 후 그 흐름을 코드로 풀어냈다.
    흐름은 아래와 같다.
  1. Storage에 파일 업로드
  2. 업로드 한 이미지의 Public_URL 반환
  3. 반환 된 이미지 URL을 메세지 전송 시
    전송하는 메세지의 필드 값에 저장하여 insert
  4. 메세지 데이터를 가져왔을 때 image_url의 필드값 유무에 따라 렌더

코드

  1. type이 file인 input을 만들어 Storage에 파일 업로드
const handleImage = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files;
    if (file) {
      // handleImageUpload로 넘겨줍니다
      handleImageUpload(file[0]);
    } else {
      return;
    }
  };
  1. 이미지를 받아 Storage에 업로드 후 public_url을 state에 저장하기
 const handleImageUpload = async (file: File) => {
    const { data, error } = await supabase.storage
      .from('images')
      .upload(`messages/${file.name}`, file, {
        contentType: file.type
      });

    if (error) {
      console.error('파일 업로드 실패:', error);
      return;
    }
    // 에러가 아니라면 스토리지에서 방금 올린 이미지의 publicURL을 받아와서
    const res = supabase.storage.from('images').getPublicUrl(data.path);
    // image 경로를 저장하는 state에 set 해주고
    setImages(res.data.publicUrl);
  };
  1. 메세지를 전송하면 해당 메세지 Row 필드값에 추가하여 insert 하기
const sendMessage = async (e: FormEvent) => {
  e.preventDefault();
  if (curUser) {
    const { data, error } = await supabase.from('chat_messages').insert([
      // 메세지 테이블에 insert 하는 row의 형태
      {
        id: uuid(),
        sender_id: curUser?.id,
        chat_room_id: clicked,
        content: chatInput,
        // 이 필드값에 public url이 담긴 state를 value로 줌.
        image_url: images
      }
    ]);
    setChatInput('');
    setImages('');

    if (error) {
      console.log('전송 실패', error);
    }
  } 
};

결과물

느낀점

  • 흐름을 파악하고 설계한 뒤
    설계대로 코드를 작성할 수 있게 되어 기쁘다🥹

0개의 댓글