Search
๐Ÿ“š

EP16. Supabase Server Side Database CRUD

์ƒ์„ฑ์ผ
2024/06/09 07:11
๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ
2024/07/06

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๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ•์˜ ์ฝ”๋“œ

7
pull