"@supabase/supabase-js": "^2.43.1"Supabase 是個人專案「用得到的猫紋」裡,放置帳號與留言資料的地方。
一開始知道 Supabase,是因為社群誇讚以網站前端的角度,想要存取資料非常容易,在搭車時快速看過,確實覺得 CRUD 都簡化得簡單易懂。Supabase 背後的運作原理是 PostgreSQL,在加入 function 或 trigger 時,會用到不少 PostgreSQL 語法。
這篇文章不會再講一次 Supabase 文件提到的功能,而是文件上找不到參考,只好到處從社群爬文記下來的做法。
接下來的內容
使用 Auth 的帳號管理功能,要把使用者資訊複製到 public 權限的表格
如果網站或 App 使用了 Supabase 的帳號管理功能,官方文件提到:建議在每個帳號建立的當下,使用 trigger 觸發 function,複製可以公開的資訊到 public 下的表格裡。
一開始不理解為什麼要這樣做,直到需顯示文章或留言的作者訊息。在 Supabase 裡,以 id 找出 auth 權限底下的使用者資料,必須有管理員權限。
透過 Foreign Key,存取使用者相關資訊
若使用者在網站上留言,常見要記錄的項目會有:留言內容、時間,以使用者的 UUID。而使用者的照片和全名等資訊,則是透過使用者的 UUID 抓取資料。這可以用 insert() 寫入資料。
const nanoid = customAlphabet('1234567890abcdef', 8);
const body = await request.json();
const postId = body?.postId;
const message = body?.message;
const createdBy = body?.createdBy;
const record = {
id: nanoid(),
post_id: postId,
message,
created_by: createdBy
};
const { error } = await supabase.from('comment').insert({
...record
});並且在 Supabase 資料庫上,把 created_by 設定 foreign key 連結至 auth.users,如果系統找不到 UUID,就會回傳錯誤。感覺很像設定完成了,而且系統會幫你把關資料是正確的。
問題
想要在讀取資料並且將使用者的公開資訊,例如:public.users 合併至一次的查詢,就不用一直使用 await supabase:
const commentsQuery = supabase
.from('comments')
.select(
`id, message, created_by:users(full_name, avatar), created_at`
)
.eq('post_id', postId);按照文件上的說明,應該可以透過 created_by 欄位的使用者 UUID 資訊,回傳 public.users 裡,對應的 full_name 和 avatar 資料。然而,這裡會出現錯誤訊息:
Could not find a relationship between 'comments' and 'users' in the schema cache❌ 嘗試修正
既然以 foreign key 連到 auth.users 的使用者 UUID,會找不到關連性,那連到 public.users 的使用者 UUID 呢?
得到無法設定 foreign key 的錯誤訊息:
foreign key constraint "users_id_fkey" cannot be implemented✅ 解決方法
建立資料的時候,不要從 supabase.from('comments').insert() 填入使用者的 UUID:
// ...
const record = {
id: nanoid(),
post_id: postId,
message
// 取消從 supabase client 填入 UUID
// created_by: createdBy
};
const { error } = await supabase.from('comment').insert({
...record
});該欄位應要以預設值的方式填入:

接著,foreign key 就可以成功連到 public.users 的 UUID:
import type { QueryData } from '@supabase/supabase-js';
const commentsQuery = supabase
.from('comments')
.select(
`id, message, created_by:users(id, full_name, avatar), created_at`
)
.eq('post_id', postId);
type CommentsFetchType = QueryData<typeof commentsQuery>;
const { data, error } = await asksQuery;就會回傳該使用者的相關資料:
"data": [{
"id": "2c62b3e0",
"message": "這個商品是在哪裡找到的呢?",
"created_by": {
"id": "f211e73d-****-****-****-************",
"email": null,
"avatar": "black.svg"
},
"created_at": "2024-06-04T12:38:06.428392+00:00"
}] 