백엔드를 직접 구축하는 일은 여전히 시간이 많이 걸립니다. 인증 로직, 데이터베이스 설계, 파일 스토리지, API 엔드포인트까지 하나씩 만들다 보면 정작 핵심 기능 개발에 집중하기 어려워집니다. Firebase가 이 문제를 해결해줬지만, NoSQL의 한계와 벤더 종속성은 늘 걸림돌이었습니다. Supabase는 PostgreSQL을 기반으로 Firebase의 편의성과 SQL의 유연성을 동시에 제공합니다.
Supabase는 오픈소스 Firebase 대안입니다. PostgreSQL 데이터베이스를 중심으로 인증, 실시간 구독, 파일 스토리지, 엣지 함수를 하나의 플랫폼에서 제공합니다. 클라우드 서비스로 사용할 수도 있고, Docker로 자체 서버에 직접 호스팅할 수도 있습니다.
-- 게시글 테이블 생성
CREATETABLEposts(idUUIDDEFAULTgen_random_uuid()PRIMARYKEY,titleTEXTNOTNULL,contentTEXT,user_idUUIDREFERENCESauth.users(id)ONDELETECASCADE,created_atTIMESTAMPTZDEFAULTNOW(),updated_atTIMESTAMPTZDEFAULTNOW());-- updated_at 자동 갱신 트리거
CREATEORREPLACEFUNCTIONupdate_updated_at()RETURNSTRIGGERAS$$BEGINNEW.updated_at=NOW();RETURNNEW;END;$$LANGUAGEplpgsql;CREATETRIGGERposts_updated_atBEFOREUPDATEONpostsFOREACHROWEXECUTEFUNCTIONupdate_updated_at();
-- RLS 활성화
ALTERTABLEpostsENABLEROWLEVELSECURITY;-- 본인 게시글만 조회 가능
CREATEPOLICY"Users can read own posts"ONpostsFORSELECTUSING(auth.uid()=user_id);-- 로그인한 사용자만 게시글 작성 가능
CREATEPOLICY"Authenticated users can insert"ONpostsFORINSERTWITHCHECK(auth.uid()=user_id);-- 본인 게시글만 수정 가능
CREATEPOLICY"Users can update own posts"ONpostsFORUPDATEUSING(auth.uid()=user_id);-- 전체 공개 게시글 조회 (별도 컬럼 활용 시)
CREATEPOLICY"Public posts are visible to all"ONpostsFORSELECTUSING(is_public=true);
// 현재 세션 확인
const{data:{session}}=awaitsupabase.auth.getSession()// 세션 변경 이벤트 구독
supabase.auth.onAuthStateChange((event,session)=>{if(event==='SIGNED_IN'){console.log('로그인:',session?.user)}if(event==='SIGNED_OUT'){console.log('로그아웃')}})
// 파일 업로드
const{data,error}=awaitsupabase.storage.from('avatars').upload(`${userId}/profile.jpg`,file,{contentType:'image/jpeg',upsert: true,// 동일 경로 파일 덮어쓰기
})// 공개 URL 생성
const{data:{publicUrl}}=supabase.storage.from('avatars').getPublicUrl(`${userId}/profile.jpg`)// 임시 서명 URL (비공개 버킷용, 1시간 유효)
const{data}=awaitsupabase.storage.from('private-docs').createSignedUrl('report.pdf',3600)
-- 본인 파일만 업로드 가능
CREATEPOLICY"Users can upload own avatar"ONstorage.objectsFORINSERTWITHCHECK(bucket_id='avatars'AND(storage.foldername(name))[1]=auth.uid()::text);
// 새 메시지 실시간 수신
constchannel=supabase.channel('messages-channel').on('postgres_changes',{event:'INSERT',schema:'public',table:'messages',filter:`room_id=eq.${roomId}`,},(payload)=>{console.log('새 메시지:',payload.new)setMessages(prev=>[...prev,payload.new])}).subscribe()// 구독 해제 (컴포넌트 언마운트 시)
return()=>{supabase.removeChannel(channel)}
// 온라인 사용자 추적
constchannel=supabase.channel('room-1')channel.on('presence',{event:'sync'},()=>{conststate=channel.presenceState()console.log('현재 접속자:',state)}).subscribe(async(status)=>{if(status==='SUBSCRIBED'){awaitchannel.track({user_id: userId,online_at: newDate()})}})
Supabase는 풀스택 개발자나 1인 개발자에게 최적화된 백엔드 플랫폼입니다. PostgreSQL의 강력함 위에 인증, 스토리지, 실시간 기능을 더한 것이 핵심입니다. Firebase에 익숙하다면 30분 안에 기본 기능을 전환할 수 있고, 처음 백엔드를 구축하는 분이라면 이 가이드의 내용만으로 실제 서비스를 시작할 수 있습니다. supabase.com에서 무료로 시작해보시기 바랍니다.