🛠️supabase 설치 & 초기세팅

npm install @supabase/supabase-js
// supabase.ts

import { Database } from "@/types/supabase";
import { createClient, SupabaseClient } from "@supabase/supabase-js";

export const supabase: SupabaseClient = createClient<Database>(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

// .env.local
NEXT_PUBLIC_KAKAO_JAVASCRIPT_KEY=6bd6d200165d9fb6d5ea07975fc636af
NEXT_PUBLIC_KAKAO_REST_API_KEY=ad2b97badcb3cc539ccfdc3ebbff1d68
NEXT_PUBLIC_SUPABASE_URL=https://xoltyjzqzjgikiubvbon.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InhvbHR5anpxempnaWtpdWJ2Ym9uIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTE2MDMzNTksImV4cCI6MjAyNzE3OTM1OX0.HoQVMHOBh0hi5KwhvEWxF48RediOz4POmSBbG8CFhdI

💾supabase database

📝기본형태

const { data, error } = await supabase
	.from('table_name')
	.select('담겨질 data의 내용')
	.eq('column', 'target_name')

from - 테이블 이름

select - data에 담긴 내용을 반환함

eq - 컬럼이 target_name과 일치하는 값을 서치함

data로 반환되는 객체는 select 안에서 만들어낸 조건으로 반환함.

.select('*') // 해당 조건(eq)을 만족한 요소가 가진 모든 컬럼을 객체로 가진 data를 반환
.select('id, user_id, room_id') // 해당 조건(eq)를 만족하는 요소의 id, user_id, room_id 를 객체로 반환

1. fetch

eq를 통해 일치하는 대상을 찾을 수 있다. 또한 match를 통해 단일 객체로 묶을 수 있다.

const { data, error } = await supabase
	.from('table_name')
	.select('column_name')
	.eq('column_1', ABC)  
	.eq('column_2', 가나다)
	.eq('column_3', 123)
	
	
	const { data, error } = await supabase
	.from('table_name')
	.select('column_name')
	.match({
		'column_1' : 'ABC',
		'column_2' : '가나다',
		'column_3' : '123'
	})

2. insert

const { data, error } = await supabase
	.from('table_name')
	.insert({column_1 : 'ABC', column_2 : '가나다' }
	.select()

여러 정보를 업로드 할 때는 배열로 감싸준다

const { data, error } = await supabase
	.from('table_name')
	.insert([{
		column_1 : 'ABC'
		column_2 : '가나다'
		}])

3. update

const { data, error } = await supabase
	.from('table_name')
	.update({column_1 : '바꿀이름'})
	.eq('column_1', 'ABC')
	.select()

2. 가입 / 로그인

2-1. 이메일 가입( 데이터만 참고로 확인하세요 )

const {data, error} = await supabase
	.auth
	.signUp({
		email,
		password,
	})
	
//이곳의 data 반환 형식은 auth 스키마의 users 테이블에 기입됨

2-2. 카카오 가입

async function signInWithKakao() {
  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'kakao',
  })
}

2-3. 구글 가입

const { data, error } = await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: {
    queryParams: {
      access_type: 'offline',
      prompt: 'consent',
    },
  },
})

3. storage

const { data, error } = await supabase
	.storage
	.from('bucket_name')
	.upload(`folder_name/to/${filename}`,
		file,
		{fileOptions} 
fileOptions = {
 contentType : image/png * 파일의 MIME타입을 정함. 
 cacheControl : 3600 * 1시간(3600초)동안 캐싱을 유지함
 upsert : false * 덮어쓰기 가능유무이며 초기값은 false임
 metadata : {key : value} * 메타데이터 첨부가능
}
//기본적으로 cacheControl만 사용해도 무관하다.

3-1 스토리지에 저장 후, url을 발급하고 싶다면

return `${process.env
        .NEXT_PUBLIC_SUPABASE_URL!}/storage/v1/object/public/images/**이하 경로**/${fileName}`

반환값으로 링크를 만들면 좋다.

bucket_name 데이터 테이블의 테이블이름이라고 생각하면 좋다.


4. realtime

const message = supabase.channel('custom-all-channel')
  .on(
    'postgres_changes',
    { event: '*', schema: 'public', table: 'message' },
    (payload) => {
      console.log('Change received!', payload)
    }
  )
  .subscribe()

기본적으로 payload.new는 새로 반영된 정보들이 표시됨

schema는 public 그대로

table은 모니터할 테이블을 지정합니다.

INSERT : 테이블에 추가되는 이벤트를 모니터
UPDATE : 테이블에 row가 변경되는 이벤트를 모니터
DELETE : 테이블에 row가 삭제되는 이벤트를 모니터
* : 테이블 내의 모든 이벤트를 모니터

작성시 payload부분을 invalidateQueries 혹은 setQueryData로 추가하도록 합시다.

realtime은 useEffect 내에서 실행시켜 언마운트시 구독을 해지하도록 배치합니다.

예시)

  useEffect(() => {
    const channel = supabase
      .channel(`chatMessage-${roomId}`)
      .on(
        'postgres_changes',
        { event: 'INSERT', schema: 'public', table: 'message', filter: `room_id=eq.${roomId}` },
        (payload) => {
          queryClient.setQueryData<IMessage[]>(['message', roomId], (oldMessages = []) => {
            return [...oldMessages, payload.new as IMessage];
          });
        }
      )
      .subscribe();

    return () => {
      channel.unsubscribe();
    };
  }, [supabase]);

작성한 ERD입니다.

erd.gif