RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-04-18中級

Rork アプリで Supabase のデータが取得できない・表示されないときの原因別対処法

Rork × Supabase でデータが表示されない原因を体系的に診断する方法を解説。RLS設定ミス・APIキーの誤り・非同期処理の落とし穴など、実際によく起きるパターンをコード例付きで紹介します。

Supabase33トラブルシューティング77RLS3データ取得デバッグ22

Rork で Supabase を使ったアプリを作ったのに、データが一向に表示されありません。そのパターン、私も何度か経験しました。

厄介なのは、エラーメッセージが出ないこともあることです。画面は正常に表示されているのに、リストが空のまま。コンソールを見ても undefined が返ってきているだけ。「Supabase の設定は合ってるはずなのに…」と途方に暮れる感覚は、初心者にとってかなり心が折れます。

ここではよくある原因を4つのパターンに絞り込んで、それぞれの診断方法と対処法を整理しています。順番に確認していただくと、多くのケースで原因を特定できると思います。

パターン1: RLS(Row Level Security)が原因 — 最も多い落とし穴

Supabase でデータが取得できないとき、原因の半分以上は RLS(行レベルセキュリティ)の設定にあります。

RLS を有効にすると、デフォルトではすべてのアクセスが拒否されます。「テーブルにデータは入っているはずなのに取れない」という状況のほとんどが、これが原因です。

診断方法

Supabase ダッシュボードの「Table Editor」を開き、テーブルを直接クリックしてみてください。データが表示される場合、アプリ側の認証状態と RLS ポリシーのズレが原因です。

次に「Authentication → Policies」でテーブルのポリシーを確認します。

-- こういう状態のとき、データが取れません
-- ポリシー: なし(有効: RLS ON)
-- すべてのユーザーからのアクセスが拒否されます
 
-- 開発中の一時的な確認用(本番では使わない)
create policy "Allow all for testing"
  on your_table
  for select
  using (true);

ログイン済みユーザーにだけデータを返す正しいポリシー

-- ユーザー自身のデータだけを読めるようにする(一般的なパターン)
create policy "Users can read their own data"
  on your_table
  for select
  using (auth.uid() = user_id);

ポイントは auth.uid() です。これは Supabase が提供する関数で、現在ログイン中のユーザーの ID を返します。テーブルの user_id カラムと一致するレコードだけが返ってきます。

ログイン前にデータを取得しようとしていませんか?

アプリ起動直後、まだログインが完了していない状態でデータを取得しようとすると、RLS によってすべて弾かれます。認証状態の確認を必ず先に行いましょう。

// ❌ 問題のあるパターン(認証確認なしでデータ取得)
useEffect(() => {
  fetchData(); // ログイン前に実行される可能性がある
}, []);
 
// ✅ 認証後にだけ取得するパターン
useEffect(() => {
  const { data: { subscription } } = supabase.auth.onAuthStateChange(
    (event, session) => {
      if (session) {
        fetchData(); // ログイン済みのときだけ実行
      }
    }
  );
  return () => subscription.unsubscribe();
}, []);

パターン2: Supabase の URL・API キーの設定ミス

意外と多いのが、.env ファイルの設定ミスです。特に複数のプロジェクトを同時に進めているときに起きやすいです。

確認すべきこと

// supabase.ts(または supabase/client.ts)
import { createClient } from '@supabase/supabase-js';
 
const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL\!;
const supabaseAnonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY\!;
 
// 開発中はこのログで確認できます
console.log('Supabase URL:', supabaseUrl?.substring(0, 30) + '...');
 
export const supabase = createClient(supabaseUrl, supabaseAnonKey);

Expo(React Native)の場合、環境変数は EXPO_PUBLIC_ で始まる必要があります。この接頭辞がないと、クライアント側のコードから変数にアクセスできません。

Supabase ダッシュボードの「Settings → API」で確認できる値と、アプリが使っている値が一致しているか確認してください。特に「anon key」と「service_role key」を間違えないよう注意が必要です(service_role key はサーバーサイドでのみ使うものです)。

Rork での環境変数設定については、Rork の環境変数・設定ミスのトラブルシューティングも参考にしてみてください。

パターン3: 非同期処理の実装ミスでデータが空になる

RLS も API キーも問題なさそうなのにデータが表示されない場合、JavaScript の非同期処理の扱いに問題があるケースです。

よくある間違いパターン

// ❌ async/await が正しく使えていない例
const fetchData = () => {
  const { data, error } = supabase
    .from('posts')
    .select('*');
  // Promiseをawaitしていないため、dataはundefinedのまま
  setData(data); 
};
 
// ✅ 正しい非同期処理
const fetchData = async () => {
  const { data, error } = await supabase
    .from('posts')
    .select('*');
  
  if (error) {
    console.error('取得エラー:', error.message);
    return;
  }
  
  setData(data ?? []); // nullの場合は空配列にする
};

await を忘れるのは本当によくある間違いです。Promise は即座に値を返さないので、await なしで data を参照すると undefined になります。

React のレンダリングタイミングの問題

// ❌ コンポーネントがマウントされる前に状態が設定される可能性
const MyComponent = () => {
  const [posts, setPosts] = useState(null); // ← null で初期化
  
  fetchData(); // useEffect外で呼び出している
  
  return <View>{posts.map(...)}</View>; // nullのときにクラッシュ
};
 
// ✅ 正しいパターン
const MyComponent = () => {
  const [posts, setPosts] = useState<Post[]>([]); // 空配列で初期化
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    const fetch = async () => {
      setLoading(true);
      const { data, error } = await supabase.from('posts').select('*');
      if (\!error && data) setPosts(data);
      setLoading(false);
    };
    fetch();
  }, []);
  
  if (loading) return <ActivityIndicator />;
  if (posts.length === 0) return <Text>データがありません</Text>;
  
  return <FlatList data={posts} renderItem={...} />;
};

初期値を null にすると .map() を呼び出したときにクラッシュします。配列を扱う場合は必ず空配列 [] で初期化するのが安全です。

パターン4: テーブル名・カラム名の間違い

地味ですが、これも頻繁に起きます。Supabase のテーブル名はデフォルトでスネークケース(user_profiles)ですが、コード側でキャメルケース(userProfiles)を使ってしまうケースです。

// ❌ テーブル名・カラム名が違う
const { data } = await supabase
  .from('userProfiles') // ← Supabase側はuser_profilesかもしれない
  .select('userName'); // ← Supabase側はuser_nameかもしれない
 
// ✅ ダッシュボードで確認した正確な名前を使う
const { data } = await supabase
  .from('user_profiles') // ← ダッシュボードで確認
  .select('user_name, avatar_url, created_at');

Supabase ダッシュボードの「Table Editor」でテーブル名とカラム名を正確に確認してから書くようにしましょう。

また、select('*') で全カラム取得してから、返ってくるデータの形を console.log で確認するのが一番手っ取り早いです。

診断フロー — 迷ったらこの順番で確認

まとめると、データが取得できないときは次の順番で確認するのが効率的です。

まずは console.log(error) を追加して、エラーメッセージを確認してください。エラーが nulldatanull の場合は、RLS が原因である可能性が高いです。エラーに「Invalid API key」が含まれる場合は API キーの問題です。

次に Supabase ダッシュボードの「Logs → API Logs」を確認します。リアルタイムでどんなクエリが飛んでいるか、ステータスコードが何かを確認できます。406 が返っている場合は RLS によるアクセス拒否が疑われます。

データベース接続エラーの詳細なトラブルシューティングや、Supabase の認証エラーを解決する方法も合わせて参考にしてみてください。

次のステップ

データが取得できるようになったら、次は実際にアプリとして動くかを実機でテストしてみましょう。シミュレーターでは再現しない問題が実機で出ることもあります。

Supabase の RLS は最初は難しく感じるかもしれませんが、一度仕組みを理解すると、細かいアクセス制御ができる強力な機能として活用できます。まずは開発中は一時的にすべてのアクセスを許可するポリシーを設定して動作確認し、リリース前に適切なポリシーに絞っていくアプローチがおすすめです。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-05-13
Supabase Storage に画像を保存したのに URL が 403 になる ─ Rork 開発でよく引っかかる RLS とバケット設定の落とし穴
RorkアプリでSupabase Storageに画像をアップロードしても URL が 403 エラーになる問題を解決します。バケットの Public/Private 設定、RLS ポリシーの SELECT 許可、getPublicUrl と createSignedUrl の使い分けという3パターンを具体的なコードで解説します。
開発ツール2026-05-11
「CORSエラー」と表示されたとき、実は別の問題が隠れている — Rork + Supabase Edge Functions
RorkアプリでSupabase Edge FunctionsをAPIとして使うとCORSエラーが出る問題を解説。React Nativeの仕組み上、実は本当のCORSエラーは起きにくく、別の根本原因が隠れていることがほとんどです。
開発ツール2026-04-22
FlatList が空白で何も映らない—Rork アプリのリスト崩れを切り分ける
Rork で生成したアプリの FlatList が真っ白で何も表示されないときに、どこから疑うべきかを順番にまとめました。data・flex・keyExtractor・親要素の高さを見直すだけで直ることも多いです。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →