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
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 를 객체로 반환
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'
})
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 : '가나다'
}])
const { data, error } = await supabase
.from('table_name')
.update({column_1 : '바꿀이름'})
.eq('column_1', 'ABC')
.select()
const {data, error} = await supabase
.auth
.signUp({
email,
password,
})
//이곳의 data 반환 형식은 auth 스키마의 users 테이블에 기입됨
async function signInWithKakao() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'kakao',
})
}
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
queryParams: {
access_type: 'offline',
prompt: 'consent',
},
},
})
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만 사용해도 무관하다.
return `${process.env
.NEXT_PUBLIC_SUPABASE_URL!}/storage/v1/object/public/images/**이하 경로**/${fileName}`
반환값으로 링크를 만들면 좋다.
bucket_name 데이터 테이블의 테이블이름이라고 생각하면 좋다.
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]);
