아웃소싱 프로젝트 PINGER) TroubleShooting 1 : supabase auth와 트리거 함수📍

밍갱·2025년 2월 27일

PROJECTS

목록 보기
15/20

1. 문제 발생🤯

01. onChange 작동이 왜 안될까

이번 프로젝트에서 담당한 부분은 로그인/회원가입이다. 지난번 게시글, 댓글 CRUD를 구현했기 때문에, 이번에는 로그인/회원가입을 담당했다. 사실 오늘 회원가입/로그인 로직을 모두 구현하고, 내일까지 zustand를 활용해서 AuthContext 구현하는 것이 목표였는데, 회원가입 로직에서부터 막혀서 계획이 전부 틀어졌다.
처음 맞닥뜨린 문제는 input의 값이 formData로 set되지 않은 것이다. 위의 이미지에서 보이다시피 input에 값을 넣고 있지만 formData는 꿈쩍도 하지 않았다.

02. 500 error : Database error saving new user

어찌저찌 input 값을 formData로 불러오는 것에 성공했다. 하지만 더 큰 시련이 다가왔으니... supabase.auth.signUp()으로 데이터를 넣어보려고 했지만 500 에러와 함께 null로 가득한 data 객체가 돌아왔다. 내가 데이터를 잘못 넣었거나 트리거 설정이 잘못된 것 같은데, 어찌 할 수가 없었다. React, JS도 겨우 찌끄리는 내가 SQL, 트리거를 잘 알리가 없지 않은가... 겨우겨우 해결한 방법을 더 까먹기 전에 정리해보고자 한다.

2. 개념 정리🧐

우선 개념을 정리하기 전에 정말 많이 도움 받았던 참고 사이트가 있어 미리 공유한다. SQL문에 대한 지식이 1도 없는 나에게 트리거 설정에 있어 한줄기 빛이 되어주었다. 이 자리를 빌어 감사의 인사를 드린다.

01. supabase 로그인/회원가입 로직 구현하기

supabase에서 회원가입 로직을 구현하면, 유저의 정보는 기본적으로 Auth schema의 users 테이블에 저장된다. auth.users는 이메일, 비밀번호, 전화번호, 사용자의 UUID 등이 저장되는데, 이외의 추가 정보(닉네임, 프로필 이미지, 주소 등)을 넣기 위해선 Public schema에 별도 테이블을 추가해주어야 한다. 그리고 테이블간의 관계를 형성하기 위해 특정 column값을 FK로 연결해주고, 한쪽 테이블에 정보가 추가되면 다른 테이블도 자동 추가되도록 trigger를 설정해야한다.

  • trigger란? : 특정 테이블에 INSERT, DELETE, UPDATE 같은 DML 문이 수행되었을 때, 데이터베이스에서 자동으로 동작하도록 작성된 프로그램

사실 SQL에 대한 기본 지식조차 없었기에, 구글링과 chatGPT에게 도움을 많이 받아 아래의 코드를 작성하였다. 그래서 이 코드가 어떻게 사용되는지 전혀 설명할 수 없다. 추후에 기회가 된다면 SQL에 대해 공부해보도록 하겠다.

  • trigger
DO $$ 
BEGIN 
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.triggers WHERE trigger_name = 'on_auth_user_created'
  ) THEN
    create trigger on_auth_user_created
after insert on auth.users
for each row execute function public.handle_create_public_user();
  END IF;
END $$;
  • trigger function : handle_create_public_user
BEGIN
  INSERT INTO public.users(user_id, created_at, nickname, address, email, role)
  VALUES (
  NEW.id,
  NEW.created_at,
  NEW.raw_user_meta_data->>'nickname',
  NEW.raw_user_meta_data->>'address',
  NEW.email,
  NEW.raw_user_meta_data->>'role'
)
ON CONFLICT (user_id) DO NOTHING;
RETURN NEW;
END;

3. 해결 방안😇

01. Input 컴포넌트 props 설정

사실 첫번째 문제는 나의 멍청한 실수였다. InputBar는 재사용성이 있다고 판단하여 공통 컴포넌트로 빼놓았는데, namevalue, onChange를 props로 내려주지 않아서 발생한 문제였다.

보이는가, 저 조촐한 props가... typeplaceholder만 내려주고 중요한 props는 전혀 전달이 되고 있지 않았다.

props를 다시 적용해주고, 확인해보았다.

input값이 formData로 잘 들어가고, 유효성 검사까지도 잘 구현되었다.

02. trigger 함수 수정

500에러는 튜터님의 도움으로 겨우 해결할 수 있었다. 우선 supabase의 로그를 꼼꼼히 확인해보았다. console.log에 찍히는 error 메세지는 한계가 있어서 어디가 문제인지 스스로 판단이 안되었다. 다행히 supabase에서 Auth에 대한 로그를 세세하게 제공하고 있었다. 이점을 튜터님께서 알려주셨고, 뒤늦게나마 로그를 천천히 다시 살펴볼 수 있었다.

*로그 보는 법 : 우측 메뉴바의 Logs - COLLECTIONS에 다양한 로그를 확인할 수 있다. 이번 문제는 회원가입 로직에서 발생한 문제였기 때문에 Auth의 로그를 확인하였다.

public.users의 role 타입에 대한 문제였다. 테이블을 세팅할 때, user의 role은 '구직자'와 '채용담당자' 뿐이서 두개 값만 존재하는 타입을 생성하여 넣어주었다. 하지만 여기서 뭔가 값에 충돌이 발생한 것으로 추측되었다.

그래서 다시 text 타입으로 변환해준 뒤, 다시 시도해보았다. 하지만 실패!

다시 로그를 확인해보니 트리거 함수에서 문제가 있었다. auth.users의 id와 public.users의 user_id가 FK로 묶여있는 상황이었는데, 이 사이에서 어떤 값을 넣고 어떤 값을 설정하는지 혼동이 있었던 것이다.

handle_create_public_user 트리거 함수를 위와 같이 수정해주었다.

4. 결과😎

01. 해결!

auth.users와 public.users가 잘 연동되는 것을 확인할 수 있었다!

02. 최종코드

  • InputBar.jsx
  • supabase trigger 함수
profile
미술 전공에서 프론트엔드 개발까지

0개의 댓글