0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Supabaseで個人開発するときにハマったエラーまとめ

0
Last updated at Posted at 2026-02-16

はじめに

個人開発で「Next.js × Supabase × Vercel」の構成を使い、筋トレ記録アプリを作っています。

Supabaseは「PostgreSQLベースのBaaS」として非常に優秀で、Auth・Storage・RLSまで一通り揃っています。
正直、Firebaseよりも「ちゃんとDBしている」感があり、個人開発との相性はかなり良いです。

しかし、実際に使ってみると分かります。

“なんとなく”では絶対に進めない。

特に以下のようなポイントで何度もハマりました。

  • user_idがnullで怒られる
  • RLSでinsertできない
    -SQL関数で謎エラー
    -本番環境でだけ動かない

この記事では、実際に遭遇したエラーとその原因、解決方法をまとめます。

1. null value in column "user_id" violates not-null constraint

エラー内容
ERROR: 23502: null value in column "user_id" violates not-null constraint

何が起きていたか

テーブル定義で user_id に NOT NULL 制約を付けていました。

user_id uuid references auth.users(id) not null

しかし、insert時に user_id を渡していなかったため、当然エラーになります。

原因

Supabase Authを使っているからといって、
user_idが自動でレコードに入るわけではない という点を理解していませんでした。

解決方法①:クライアント側で明示的に渡す

const {
  data: { user }
} = await supabase.auth.getUser()

await supabase.from("user_plan_progress").insert({
  user_id: user?.id,
  weight: 60,
  completed_sessions: 0
})

解決方法②:DB側でdefaultを設定する(おすすめ)

user_id uuid references auth.users(id) default auth.uid()

この設定をすると、insert時に明示しなくても auth.uid() が自動で入ります。

個人的にはDB側で担保する方が安全 だと感じました。

2. RLSでinsertできない(エラーが出ないのに保存されない)

これが一番ハマりました。

症状

insert処理は成功しているように見える

エラーは出ない

でもデータが入らない

原因

RLS(Row Level Security)が有効で、ポリシーを書いていなかった。

SupabaseではRLSが有効なテーブルに対して、
明示的なpolicyがないと操作できません。

解決方法

CREATE POLICY "Users can insert their own data"
ON user_plan_progress
FOR INSERT
WITH CHECK (auth.uid() = user_id);

さらに、SELECTも必要です。

CREATE POLICY "Users can read their own data"
ON user_plan_progress
FOR SELECT
USING (auth.uid() = user_id);

RLSを有効にしている場合は、

INSERT

SELECT

UPDATE

DELETE

それぞれにポリシーが必要です。

ここを理解していないと、永遠に「なぜか動かない」状態になります。

3. multiple assignments to same column エラー

エラー内容
ERROR: 42601: multiple assignments to same column "completed_sessions"

原因

SQL関数内で同じカラムを二重代入していました。

UPDATE user_plan_progress
SET completed_sessions = completed_sessions + 1,
    completed_sessions = 0
WHERE id = target_id;

当然ですが、同じカラムを2回代入しているのでエラーになります。

学び

SupabaseのSQL Editorは便利ですが、
関数ロジックのチェックは自分でやるしかない。

アプリ側だけでなく、SQLもちゃんとレビューする必要があります。

4. SERVICE_ROLE_KEYとANON_KEYの違いを理解していなかった

Supabaseには2種類のキーがあります。

NEXT_PUBLIC_SUPABASE_ANON_KEY

クライアント側で使用

RLSが適用される

ブラウザ公開OK

SUPABASE_SERVICE_ROLE_KEY

サーバー専用

RLSを無視できる

絶対にクライアントに出してはいけない

Next.jsでAPI Routeを使う場合、サーバー側ではSERVICE_ROLE_KEYを使用できます。

例えば:

import { createClient } from "@supabase/supabase-js"

const supabaseAdmin = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
)

管理系処理やバッチ処理は、こちらで実装するのが安全です。

5. Vercelデプロイ後に動かない問題

ローカルでは動くのに、本番では動かない。

原因はほぼこれです。

環境変数をVercelに登録していない。

Vercel → Project → Settings → Environment Variables

以下を必ず登録します。

NEXT_PUBLIC_SUPABASE_URL

NEXT_PUBLIC_SUPABASE_ANON_KEY

SUPABASE_SERVICE_ROLE_KEY

ローカルの .env.local は本番には反映されません。

Supabaseを使って感じたこと

Supabaseは確かに便利です。

しかし、

RLSを理解していない

認証とDB設計が曖昧

キーの責務を理解していない

この状態だと確実にハマります。

逆に言えば、
DB設計力とセキュリティ意識が一気に鍛えられる環境 でもあります。

個人開発でSupabaseを使うのは本当におすすめです。

ただし、「なんとなく使う」のではなく、
PostgreSQLの思想を理解しながら使うと、学習効率が一気に上がります。

まとめ

Supabaseで個人開発するときにハマりやすいポイントは:

user_idの扱い

RLSの理解不足

SQL関数のロジックミス

環境変数の設定漏れ

もし同じように詰まっている方がいれば、
まずはRLSとuser_idの設計を疑ってみてください。

Supabaseは「楽」ですが、「浅く使う」ことはできません。

その分、ちゃんと使えば確実に力になります。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?