アクセスルール
新しいテーブルがなぜ空に見えるのか。このプラットフォームで最もよく間違えるところなので、最初に読んでください。
アクセスルール(RLS)
このプラットフォームで最もよく間違えるところです。エラーにならず空のリストが返ってくるため、間違えたことに気づきません。
必ず知っておくこと
新しく作ったテーブルは、アクセスルールが有効な状態で作られ、ルールはひとつもありません。 ルールがなければ、そのテーブルは誰にも見えません。エラーではなく空の配列が返ってきます。
create table notes (id uuid primary key default gen_random_uuid(), body text);
-- 今、公開キーで select すると: [] (エラーではない)ロール名
プロジェクトごとに異なります。固定の anon/authenticated ではありません。
list_policies が、そのプロジェクトの実際のロール名を3つ教えてくれます。
| ロール | 誰か |
|---|---|
<ref>_anon | ログインしていない人 |
<ref>_authenticated | ログインしている人 |
<ref>_service_role | サーバー。ルールをすべて迂回します |
Supabase向けに書いたSQLはそのまま実行できます(Supabase名の変換)。 run_sql、query_sql、apply_migrations、コンソールのSQLエディター、oneend db pushでは、
public.、auth.、storage.をapp_<ref>.、auth_<ref>.、stor_<ref>.に、to/fromの後のanon、authenticated、service_roleをこのプロジェクトのロールに変換して実行します。
名前を指す文字列('public.orders'::regclass、to_regclass('public.orders')、'public'::regnamespace)のスキーマも変換します。
何を変換したかは応答のtranslatedにあります。それ以外の文字列とコメントは変換せず、直接接続(psql)も変換しません。
すべての実行は search_path が app_<ref>, auth_<ref>, public, extensions の状態で動くので、スキーマを付けない create table orders や 'orders'::regclass もこのプロジェクトのものを指します。
よくあるルール3つ
-- 誰でも読めるように
create policy "public read" on notes for select to <ref>_anon using (true);
-- ログインした本人の行だけ
create policy "own rows" on notes for all to <ref>_authenticated
using (user_id = auth_<ref>.uid());
-- ログインした人は書けるが、他人の名前では書けないように
create policy "insert own" on notes for insert to <ref>_authenticated
with check (user_id = auth_<ref>.uid());using は読むときに、with check は書くときに確認されます。insert に using だけを付けると、誰も書けません。
確認のしかた
list_policies でルールを確認し、read_rows で公開キーから実際に見えるかを確かめてください。
テーブルを作ったりルールを変えたりした後は、get_advisors で RLS が無効なテーブルや誰でも書けるルールなどの問題がないかを確認してください。
アプリが起動するたびに実行する SQL(Figma Make の kv_store など)では、インデックスに名前を付けて if not exists を使ってください: create index if not exists kv_store_x_key_idx on kv_store_x (key text_pattern_ops);。名前のない create index on … は実行するたびに同じインデックス(_idx1、_idx2…)をもう一つ作り、書き込みのたびにそのすべてを更新します。get_advisors の duplicate_index が、1つだけ残す drop index を一緒に示します。
ルールを作ったのにまだ空なら、ロール名が間違っている可能性が最も高いです。