EP16. Supabase Server Side Database CRUD
Supabase์ ๋ฐฑ์๋ ํจ์ ๋ก์ง์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ค๋ฃจ๋ ๋ฐฉ์์ ํ์ตํฉ๋๋ค.
userRepository์ ๊ตฌํํ๋ ๋ชจ์ ๋ก์ง์ ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ค๋ฃจ๋ ์ฝ๋๋ก ๋ณ๊ฒฝํ๊ฒ ์ต๋๋ค.
1. Database Fetch Data
fcm_tokens ํ
์ด๋ธ์์ user_id์ ํด๋นํ๋ ํ ํฐ ๋ชฉ๋ก์ ์กฐํํ๋ ๋ก์ง์ ๊ตฌํํ๊ฒ ์ต๋๋ค.
export class UserRepository {
// userID๋ฅผ ์ด์ฉํด ํด๋น ์ ์ ์ FCM ํ ํฐ ๋ชฉ๋ก์ ๋ฐํํ๋ ํจ์
async getFCMTokensByUserID(userID: string): Promise<string[]> {
// fcm_tokens ํ
์ด๋ธ์์ ํด๋น ์ ์ ์ FCM ํ ํฐ์ ์กฐํ
const { data: tokensData, error: tokensError } = await supabase
.from("fcm_tokens")
.select("fcm_token")
.eq("user_id", userID);
// ์กฐํ ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ๋น ๋ฐฐ์ด ๋ฐํ
if (tokensError) {
console.error("Error fetching FCM tokens:", tokensError.message);
return [];
}
// FCM ํ ํฐ ๋ฐฐ์ด ๋ฐํ
return tokensData.map((token: { fcm_token: string }) => token.fcm_token);
}
}
TypeScript
๋ณต์ฌ
โข
Supabase Fetch Data ๊ฐ์ด๋
from, select, eq ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ fcm_tokens ํ
์ด๋ธ์์ user_id์ ํด๋นํ๋ fcm_token ๋ชฉ๋ก์ ์กฐํํฉ๋๋ค.
2. Database Insert Data
// userID์ fcmToken์ ์ธํ์ผ๋ก ๋ฐ์์ DB์ ์ถ๊ฐ ๋๋ ์
๋ฐ์ดํธํ๋ ํจ์
async addFCMToken(userID: string, fcmToken: string): Promise<boolean> {
// fcm_tokens ํ
์ด๋ธ์์ ๋์ผํ fcmToken์ด ์กด์ฌํ๋์ง ํ์ธ
const { data: existingToken, error: selectError } = await supabase
.from("fcm_tokens")
.select("*")
.eq("fcm_token", fcmToken)
.single();
// ์ ํ ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด false ๋ฐํ
if (selectError && selectError.code !== "PGRST116") { // 'PGRST116'์ no rows ์๋ฌ ์ฝ๋
console.error("Error selecting FCM token:", selectError.message);
return false;
}
// ๋์ผํ fcmToken์ด ์กด์ฌํ๋ฉด user_id๋ฅผ ์
๋ฐ์ดํธ
if (existingToken) {
const { error: updateError } = await supabase
.from("fcm_tokens")
.update({ user_id: userID })
.eq("fcm_token", fcmToken);
// ์
๋ฐ์ดํธ ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด false ๋ฐํ
if (updateError) {
console.error("Error updating FCM token:", updateError.message);
return false;
}
// ์ฑ๊ณต์ ์ผ๋ก ์
๋ฐ์ดํธ๋๋ฉด true ๋ฐํ
return true;
} else {
// ๋์ผํ fcmToken์ด ์์ผ๋ฉด ์๋ก์ด ํ ์ถ๊ฐ
const { error: insertError } = await supabase
.from("fcm_tokens")
.insert([{ user_id: userID, fcm_token: fcmToken }]);
// ์ฝ์
์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด false ๋ฐํ
if (insertError) {
console.error("Error inserting FCM token:", insertError.message);
return false;
}
// ์ฑ๊ณต์ ์ผ๋ก ์ฝ์
๋๋ฉด true ๋ฐํ
return true;
}
}
TypeScript
๋ณต์ฌ
3. Database Delete Data
export class UserRepository {
// userID์ fcmToken์ ์ธํ์ผ๋ก ๋ฐ์์ DB์์ ์ญ์ ํ๋ ํจ์
async deleteFCMToken(userID: string, fcmToken: string): Promise<boolean> {
// fcm_tokens ํ
์ด๋ธ์์ FCM ํ ํฐ ์ญ์
const { error: deleteError } = await supabase
.from("fcm_tokens")
.delete()
.eq("user_id", userID)
.eq("fcm_token", fcmToken);
// ์ญ์ ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด false ๋ฐํ
if (deleteError) {
console.error("Error deleting FCM token:", deleteError.message);
return false;
}
// ์ฑ๊ณต์ ์ผ๋ก ์ญ์ ๋๋ฉด true ๋ฐํ
return true;
}
}
TypeScript
๋ณต์ฌ
4. ๋ฐฐํฌ
bash deploy.sh
TypeScript
๋ณต์ฌ
5. API ํธ์ถ ๊ฒฐ๊ณผ
์น ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด FCM ํ ํฐ ๋ชฉ๋ก ์กฐํ API๋ฅผ ํธ์ถํ๋ฉด ํค๋์ ์ธ์ฆ์ ๋ณด๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ธ์ฆ ๋ฏธ๋ค์จ์ด์์ 401 Response๋ฅผ ๋ฐํํฉ๋๋ค.