簡介
- Firebase | Google's Mobile and Web App Development Platform
- Supabase is an open source Firebase alternative. Start your project with a Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, and Vector embeddings.
Firebase | Supabase | |
---|---|---|
Auth | ✅ | ✅ |
Functions | ✅ Cloud Functions | ✅ Edge Functions |
Realtime subscriptions | ✅ Realtime Database | ✅ |
Storage | ✅ | ✅ |
Database | NoSQL | Postgresql |
Hosting | ✅ | ❌ |
基本上就是Firebase的平替
為什麼我選了Supabase?
主要還是因為我之前使用firebase的經驗不是很好,文件有點難翻 同時提供了可以Self-hosted的選項
-
Supabase免費計畫
- 無限制 API 請求
- 社交 OAuth 提供者
- 最多 500MB 資料庫空間
- 最多 1GB 文件儲存
- 最多 5GB 頻寬
- 最多 50MB 文件上傳
- 最多 50,000 每月活躍用戶
- 最多 500K 邊緣功能調用
- 最多 200 並發即時連接
- 最多 200萬即時消息
- 1天日誌保留
- 社區支持
空閒項目在1週無活動後會被暫停。
下面會基於我有使用過的部分作簡介,同時偷偷推廣我做的玩具
喔對 還有另一個玩具
玩具內容
目標
看 楓棠兒__ 每月要發一次XXX訂閱 XXX小奇點 XXX贈訂 看起來頗辛苦的 故產出這個東西
目前架構
-
使用Supabase的Auth+Database+Edge Function
- Auth只用了Email Magic Link
- Database
- Edge Function
- 寫了一下Twitch Oauth Code Flow
- Token Revoke
- Token Refresh
-
用FastAPI 簡單做了Agent Container的操作
- C
RUD
- C
-
流程
- 在Agent Container建立之後,由TwtichPubSubAPI 傳送資料,並回傳到Supabase Database
技術選擇
前端
- Nuxt3
最近在玩Nuxt 3 偷懶不用import和處理route的感覺太好了LUL
後端
- Supabase
- 資料取得方式 (下面用訂閱的內容作比較)
- Webhook
欄位 類型 描述 user_id string 用戶訂閱指定頻道的用戶ID。 user_login string 用戶訂閱指定頻道的登錄名。 user_name string 用戶訂閱指定頻道的顯示名稱。 broadcaster_user_id string 請求的廣播者ID。 broadcaster_user_login string 請求的廣播者登錄名。 broadcaster_user_name string 請求的廣播者顯示名稱。 tier string 訂閱的層級。有效值為1000、2000和3000。 is_gift boolean 訂閱是否為禮物。 - Pubsub
欄位 類型 描述 channel_id string 已訂閱或已贈送的頻道的ID。 channel_name string 已訂閱或已贈送的頻道的名稱。 context string 與訂閱產品關聯的事件類型,取值:sub、resub、subgift、anonsubgift、resubgift、anonresubgift。 data JSON 包裝了主題和消息欄位。 user_id string 訂閱或發送禮物訂閱的人的用戶ID。 user_name string 訂閱或發送禮物訂閱的人的登錄名。 display_name string 訂閱或發送禮物訂閱的人的顯示名稱。 message string 用戶輸入的重新訂閱消息的正文。根據消息類型,消息正文包含不同的欄位。 months int 贈送者在頻道中已贈送的累計月數(已棄用)。 recipient_id string 訂閱禮物接收者的用戶ID。 recipient_user_name string 訂閱禮物接收者的登錄名。 recipient_display_name string 訂閱禮物接收者的顯示名稱。 sub_plan string 訂閱計劃ID,取值:Prime、1000、2000、3000。 sub_plan_name string 頻道特定的訂閱計劃名稱。 time string 訂閱或禮物完成的時間。RFC 3339格式。 topic string 消息所涉及的主題。 type string 有效值:MESSAGE。 cumulative_months string 訂閱的累計月數。 streak_months string 表示用戶在頻道中最近(和連續的)訂閱時期的月數。 is_gift bool 如果此訂閱消息是由禮物訂閱引起的。 multi_month_duration int 單個多月禮物的月數或作為多月訂閱的一部分購買的月數。
- Webhook
恩 其實我也沒比較 我就是想用websocket去接資料回來
選完剛好官方docs有 Supabase-QuickStart-Nuxt3 教學
Supabase
Auth
- 官方文件
- 這邊有很多Provider 但,畢竟還是有收費方案的,Self-hosted就沒這麼多選擇了,好像剩下email、phone跟傳統的帳號密碼登入
- 在Nuxt3 QuickStart裡 使用的是 在v1.0.1之後,多了一個redirect的選項,如果你做的是SPA,那會有應該要登入了,但卻沒有登入的情況發生,我這邊是把redirect關掉 就可以照著QuickStart的教學做
或是你想用新的v1.0.1以上 作者有提供更新教學
- 登入有範例 特別簡單
- 登入狀態
Edge Functions
Docs算清楚,只是本地測試要起一堆container
所以我就沒在本地測試,上去之後邊試邊補
console.log()
姑且是算功能正常
- GrantToken
- RevokeToken
- RefreshToken
Database
在Supabase上,當Table建立出來之後,你就直接擁有CRUD相關的API,透過PostgreSQL的RLS Policy可以對API的存取做限制,
-
建立Table
-
API Docs
- Insert
- Update
- Read
- Del
-
- 有時侯,你的原始資料可能要有其他操作或跟其他的表去做Join,才能取得你可用的資料,這邊就可以用View在Database裡面建立。
這邊我也不是很熟,我只是不想在前端多打那麼多次API去操作資料,所以在DB裡面用SQL去做
1
create or replace view "XXXX" with (security_invoker = on) as select ABC from BCD ;
- 這邊有個很重要的,如果你希望你的View,也有跟取資料的Table有一樣的限制,那在建立View的時候要
with (security_invoker = on)
-
- 在DB被操作(INSERT,UPDATE,DELETE),可以Trigger你建立好的Function
- QuickStart裡面有提供在User Register的時候=>User被建立(INSERT)的Trigger
1 2 3 4 5 6 7 8 9 10 11 12 13
create function public.handle_new_user() returns trigger as $$ begin insert into public.profiles (id, full_name, avatar_url) values (new.id, new.raw_user_meta_data->>'full_name', new.raw_user_meta_data->>'avatar_url'); return new; end; $$ language plpgsql security definer; create trigger on_auth_user_created -- 建立了一個Trigger after insert on auth.users -- 在auth.users insert之後 for each row -- 每一行都 execute procedure public.handle_new_user(); -- 執行上面的function
註解有誤在麻煩各位告知
-
Http in PSQL
-
- 還沒v1.0
- 提供的API不完整-只有get/post
- 但他是Async
我腦子抽風才選這個
- 一點範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
CREATE OR REPLACE function create_container() returns trigger AS $$ DECLARE login TEXT; declare token text; declare apiUrl CONSTANT text:='https://twitchtoolapi.virgil246.eu.org/twitch_list'; begin set role pgsodium_keyiduser; -- 偷偷的換一下Role拿Key select secret from vault.decrypted_secrets where decrypted_secret='BackenAPIToken' into token; set role authenticated; SELECT username FROM profiles WHERE NEW.user=profiles.id INTO login; PERFORM net.http_post( apiUrl, headers := format('{"X-KEY": "%s"}',token)::JSONB, body:=format('{"action":"new","token": "%s","login":"%s"}', NEW.access_token,login)::JSONB ); RETURN NEW; end; $$ language plpgSQL; CREATE OR REPLACE trigger new_token after insert on public."TwitchToken" for each row execute procedure create_container();
把建立container的操作跟Token Insert綁再一起
PERFORM
不在意SQL語句結果的話用這個 -
- 至少V1.0版了
但我沒用
-
再補一兩個類似的服務吧 但我就沒用過了
https://appwrite.io/
https://kinde.com/ 這個應該就只針對登入
完了本來以為會是一篇稍微有用的 看完比較像是自己的開發紀錄
下面有我的聯絡方式 有問題可以留言或直接連絡我
有問題可以在下方utterances留言喔