Supabase Auth는 Postgres DB의 auth 스키마를 사용하여 사용자 테이블 및 기타 정보를 저장합니다. 
기본적으로 User metadata는 auth 스키마의 users 테이블 raw_user_meta_data 컬럼에 저장됩니다. 이 정보를 활용하는 방법을 고려해봤지만, 추후 API를 통해 사용자 데이터에 접근하려 했을 때 auth 스키마는 보안을 위해 자동 생성된 API에 노출되지 않기 때문에 public 스키마에 별도의 사용자 테이블을 만들어 관리하기로 결정했습니다. 
이번 포스팅에서는 이 부분에 대해 다루겠습니다.
SQL문을 사용하여 테이블을 직접 생성할 수도 있지만, 빠르게 생성하기 위해 대시보드를 사용했습니다.
상기 이미지에서 Foreign keys 부분을 보면 기본키(id)를 auth 스키마의 users 테이블에 대한 외래키 참조로 사용한 것을 확인할 수 있습니다. 
사용자가 회원가입하거나 소셜 로그인을 할 때마다 public 스키마의 users 테이블 정보를 업데이트 하기 위해 다음과 같이 트리거를 설정하였습니다. 
-- 무작위 닉네임 생성 함수
create or replace function public.generate_random_nickname()
returns text as $$
declare
  new_nickname text;
begin
  -- 무작위 닉네임 생성 (여기서는 단순히 랜덤 문자열을 사용)
  new_nickname := 'user_' || substr(md5(random()::text), 1, 8);
  -- 닉네임이 중복되지 않는지 확인
  while exists (select 1 from public.users where nickname = new_nickname) loop
    new_nickname := 'user_' || substr(md5(random()::text), 1, 8);
  end loop;
  return new_nickname;
end;
$$ language plpgsql;
create or replace function public.handle_new_user() 
returns trigger as $$
declare
  final_nickname text;
  birth_value text;
  gender_value text;
  profile_url_value text;
  updated_raw_user_meta_data jsonb;
begin
  -- 1️⃣ `public` 스키마의 `users` 테이블에 데이터 추가
  -- 🏷️ A. generate_random_nickname 함수를 이용하여 무작위 닉네임 생성
  if new.raw_user_meta_data->>'nickname' is null then
    final_nickname := public.generate_random_nickname();
  else
    final_nickname := new.raw_user_meta_data->>'nickname';
  end if;
  -- 생년월일, 성별, 프로필 URL 값 설정
  birth_value := new.raw_user_meta_data->>'birth';
  gender_value := new.raw_user_meta_data->>'gender'; 
  profile_url_value := new.raw_user_meta_data->>'profileUrl';
  -- public.users 테이블에 데이터 삽입
  insert into public.users (
    id, email, nickname, birth, gender, age_flag, privacy_flag, terms_flag, profile_url
  )
  values (
    new.id,
    new.email,
    final_nickname,
    birth_value::date,
    gender_value,
    (new.raw_user_meta_data->>'ageFlag')::boolean, 🏷️ B. ::boolean
    (new.raw_user_meta_data->>'privacyFlag')::boolean,
    (new.raw_user_meta_data->>'termsFlag')::boolean,
    profile_url_value
  );
  -- 2️⃣ 소셜 로그인을 진행할 경우 상기 코드에서 무작위로 생성한 닉네임을 metadata에 업데이트 하기 위함
  -- 🏷️ C. jsonb_build_object
  updated_raw_user_meta_data := jsonb_build_object(
  'nickname', final_nickname,
  'birth', birth_value,
  'gender', gender_value,
  'profileUrl', profile_url_value
  );
  update auth.users
  set 
    raw_user_meta_data = updated_raw_user_meta_data
  where id = new.id;
  return new;
end;
$$ language plpgsql security definer;
-- 트리거 정의
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();
1️⃣ 설명
-> 기본적으로 함수와 트리거를 이용하여 auth 스키마의 users 테이블에 새로운 데이터가 추가되면
public 스키마의 users 테이블에 자동으로 데이터를 추가합니다.
(참고: User Management)
🏷️ A. 무작위 닉네임 생성 함수 사용 이유
-> 일반적인 회원가입 과정을 통해 nickname (필수값, 유니크)을 받아서 users 테이블에 저장할 수 있지만,
소셜 로그인을 통해 진행할 경우 nickname 값을 받아올 수 없어 유니크한 값을 생성하기 위해 사용합니다.
🏷️ B. 타입 작성
-> text 타입의 필드를 조작할 때는 별도 타입을 지정할 필요가 없지만,
그 외의 타입은 Database error saving new user 오류가 발생하므로 다음과 같이 작성해야합니다.
(ex: ::boolean, ::date)
2️⃣ 설명
-> 소셜 로그인을 진행할 경우, auth.users -> public.users 형태에서 무작위로 생성한 nickname이 auth.users의 metadata 에 반영되도록 하기 위함입니다.
🏷️ C. jsonb_build_object (링크 참고)
-> JSON 객체 작성
jsonb
- PostgreSQL 9.4 버전에서 새롭게 제공되는 자료형입니다.
 - 바이너리 형식으로 저장되어 입력 속도는 약간 느리지만, 구문 분석할 필요가 없어 처리 속도가 훨씬 빠르며 인덱싱을 지원합니다.
 - 객체 키의 순서를 보존하지 않으며, 중복된 객체 키를 유지하지 않습니다.
 
(입력에 중복 키가 지정된 경우 마지막 값만 유지됩니다.)- 자세한 내용은 링크를 참고해주세요.