アンケートを収集するアプリは、ビジネスの現場でも個人プロジェクトでも幅広く活躍します。顧客満足度調査、社内投票、イベント後のフィードバック収集——どれも「スプレッドシートよりも使いやすい専用アプリが欲しい」という声をよく耳にします。
ここではRork を使ってアンケートアプリをゼロから構築する手順を丁寧に解説します。ラジオボタン・テキスト入力・チェックボックスの複数回答形式、Supabase を活用した回答データの保存、そして集計グラフの表示まで、初心者の方でも 1 日で完成できる内容を目指しました。
この記事で作るもの
完成するアプリの主な機能は次の通りです。
- 複数の質問形式(単一選択・複数選択・自由記述)をサポートするアンケートフォーム
- 回答を Supabase に保存するバックエンド連携
- 回答数・回答比率を棒グラフで表示する集計ダッシュボード
- 回答済み状態の管理(同じユーザーによる重複回答を防ぐ)
対象読者は、Rork でアプリを作り始めたばかりの方です。React Native の深い知識は不要ですが、Rork の画面作成と基本的なプロンプト操作には慣れていることを前提にしています。
前提知識・環境準備
アプリの作成を始める前に、以下を準備しておきましょう。
- Rork アカウント(無料プランで十分。より高度なネイティブ機能を使う場合は Rork Max を検討)
- Supabase アカウント(無料枠で OK。データベースと API キーを準備します)
- アンケートの設計(質問文・選択肢を事前にメモしておくとスムーズです)
Supabase の設定は後述しますが、アカウント登録と新規プロジェクトの作成だけ先に済ませておくと作業がスムーズです。
アンケートアプリの基本設計
画面構成
今回作るアプリは 3 つの画面で構成します。
- ホーム画面(アンケートの一覧と説明)
- 回答フォーム画面(質問を 1 問ずつ表示するステップ式 UI)
- 集計ダッシュボード画面(回答結果をグラフで可視化)
データ構造
Supabase に以下の 2 つのテーブルを用意します。
surveys テーブル
id uuid (主キー)
title text
created_at timestamp
responses テーブル
id uuid (主キー)
survey_id uuid (surveys の外部キー)
question_id text
answer text
created_at timestamp
answer カラムには単一選択の場合は選択肢の文字列、複数選択の場合はカンマ区切りの文字列、自由記述の場合はそのまま回答テキストを格納します。シンプルな設計ですが、MVP(最小実行可能プロダクト)としては十分です。
Rork でのアンケートアプリ実装
Step 1: Supabase のセットアップ
Supabase のダッシュボードから新しいプロジェクトを作成し、SQL エディタで以下のコードを実行してテーブルを作成します。
-- surveys テーブルの作成
CREATE TABLE surveys (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
title text NOT NULL,
description text,
created_at timestamp DEFAULT now()
);
-- responses テーブルの作成
CREATE TABLE responses (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
survey_id uuid REFERENCES surveys(id) ON DELETE CASCADE,
question_id text NOT NULL,
answer text NOT NULL,
respondent_id text, -- デバイス固有IDで重複回答を防ぐ
created_at timestamp DEFAULT now()
);
-- 誰でも回答を挿入・読み取りできる RLS ポリシー(公開アンケート用)
ALTER TABLE surveys ENABLE ROW LEVEL SECURITY;
ALTER TABLE responses ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Public surveys are viewable by everyone" ON surveys
FOR SELECT USING (true);
CREATE POLICY "Anyone can submit a response" ON responses
FOR INSERT WITH CHECK (true);
CREATE POLICY "Responses are viewable by everyone" ON responses
FOR SELECT USING (true);テーブルを作成したら、Settings → API から URL と anon key をメモしておきます。
Step 2: Rork でプロジェクトを作成する
Rork を開き、新規プロジェクトを作成してから、次のプロンプトを入力します。
アンケート収集アプリを作ってください。
以下の機能が必要です:
1. ホーム画面にアンケートのタイトルと説明を表示
2. 「回答する」ボタンで質問フォームに移動
3. 質問は3種類の形式をサポート:
- 単一選択(ラジオボタン)
- 複数選択(チェックボックス)
- 自由記述(テキスト入力)
4. 全問回答後に「送信」ボタンで Supabase に保存
5. 集計ダッシュボードで回答数と選択肢ごとの割合を棒グラフで表示
カラースキームはブルー系でシンプル・クリーンなデザインにしてください。
Rork が画面の骨格を自動生成してくれます。まずは UI の確認から始め、細部を調整していきましょう。
Step 3: 回答フォームの実装
Rork が生成したコードを確認しながら、質問フォームのロジックを追加します。質問データはアプリ内に定数として持たせるシンプルな方法を使います。
// questions.ts — アンケートの質問データ定義
export const SURVEY_QUESTIONS = [
{
id: "q1",
type: "single", // 単一選択
text: "現在のアプリ開発経験を教えてください",
options: ["未経験", "独学で学習中", "個人アプリを公開済み", "プロとして開発"],
},
{
id: "q2",
type: "multiple", // 複数選択
text: "使用したことがある開発ツールを選んでください(複数可)",
options: ["Rork", "FlutterFlow", "Adalo", "Bubble", "Bolt", "なし"],
},
{
id: "q3",
type: "text", // 自由記述
text: "アプリ開発で困っていることを自由にお書きください",
},
];Rork にこのデータを参照させながら、ステップ式の質問表示(1 問ずつ進む形式)を実装します。
Step 4: Supabase への回答保存
環境変数に Supabase の接続情報を設定し、回答送信時の処理を実装します。
// supabase.ts — Supabase クライアントの初期化
import { createClient } from "@supabase/supabase-js";
const SUPABASE_URL = process.env.EXPO_PUBLIC_SUPABASE_URL!;
const SUPABASE_ANON_KEY = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!;
export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
// 回答を一括保存する関数
export async function submitSurveyResponses(
surveyId: string,
answers: Record<string, string | string[]>,
respondentId: string
) {
const rows = Object.entries(answers).map(([questionId, answer]) => ({
survey_id: surveyId,
question_id: questionId,
// 複数選択の場合は配列をカンマ区切り文字列に変換
answer: Array.isArray(answer) ? answer.join(",") : answer,
respondent_id: respondentId,
}));
const { error } = await supabase.from("responses").insert(rows);
if (error) {
console.error("回答の保存に失敗しました:", error.message);
throw error;
}
return { success: true };
}respondentId には expo-device や AsyncStorage で生成した端末固有の UUID を使うことで、同じデバイスからの重複回答を防げます。
Rork に次のプロンプトで統合を依頼しましょう。
回答送信ボタンを押したとき、上記の submitSurveyResponses 関数を呼び出して
Supabase に保存し、保存完了後に「回答ありがとうございました!」という
お礼画面に遷移する処理を追加してください。
送信中はローディングスピナーを表示してください。
Step 5: 集計ダッシュボードの実装
回答データを Supabase から取得し、グラフで表示します。React Native でグラフを描画するには react-native-chart-kit が手軽です。
// useResponseStats.ts — 集計データを取得するカスタムフック
import { useEffect, useState } from "react";
import { supabase } from "./supabase";
interface AnswerCount {
option: string;
count: number;
percentage: number;
}
export function useResponseStats(surveyId: string, questionId: string) {
const [stats, setStats] = useState<AnswerCount[]>([]);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchStats() {
const { data, error } = await supabase
.from("responses")
.select("answer")
.eq("survey_id", surveyId)
.eq("question_id", questionId);
if (error || !data) return;
// 回答の集計処理
const countMap: Record<string, number> = {};
data.forEach(({ answer }) => {
// カンマ区切り(複数選択)にも対応
answer.split(",").forEach((opt: string) => {
countMap[opt.trim()] = (countMap[opt.trim()] || 0) + 1;
});
});
const totalCount = data.length;
const statsArray = Object.entries(countMap).map(([option, count]) => ({
option,
count,
percentage: Math.round((count / totalCount) * 100),
}));
setStats(statsArray);
setTotal(totalCount);
setLoading(false);
}
fetchStats();
}, [surveyId, questionId]);
return { stats, total, loading };
}チャートのレンダリングについては、Rork アプリにインタラクティブなチャートを実装する — Victory Native 実践ガイド で詳しく解説していますので、グラフ表示で行き詰まった際はあわせてご覧ください。
よくあるエラーと対処法
エラー 1: 「Row-level security policy violation」
Supabase の RLS(行レベルセキュリティ)の設定が不足しているために起こります。前述の SQL で CREATE POLICY 文を実行済みか確認してください。ポリシーが正しく設定されていれば、anon キーで問題なく読み書きできます。
エラー 2: 「Cannot read property of undefined」(質問データが表示されない)
質問データの読み込み前にレンダリングが走っているケースです。フックやコンポーネントの初期値に適切なデフォルト値(空配列 [] など)を設定し、データ取得中はスケルトンや ActivityIndicator を表示するよう Rork に依頼しましょう。
エラー 3: 重複回答が保存されてしまう
respondentId が毎回異なる値になっていないか確認します。アプリ起動時に一度だけ UUID を生成して AsyncStorage に保存し、以後はそのキャッシュを使う実装にすることで解決できます。
応用アイデアと収益化
基本的なアンケートアプリが動いたら、次のような機能追加で実用性が大きく高まります。
- 質問の動的管理: Supabase に質問データを移してダッシュボードから編集できるようにすることで、コードを変更せずにアンケート内容を更新できます
- 期限・締め切り設定: 回答期限を設けることで、期間限定キャンペーンや社内投票に活用できます
- CSV エクスポート: 集計結果を CSV でダウンロードできる機能はビジネス用途で重宝されます
- SaaS 展開: 複数のアンケートを管理できる SaaS 型に発展させれば、月額課金サービスとして展開できます。収益化の設計についてはRork × Supabase Realtime でリアルタイム分析ダッシュボードを構築する完全ガイドが参考になります
全体を振り返って
ここではRork を使ってアンケート収集アプリを構築する基本的な流れを解説しました。
- Supabase でデータベースとテーブルを準備する
- Rork に質問フォームの骨格を生成してもらい、質問データと統合する
- 回答を Supabase に保存し、集計してグラフで可視化する
アンケートアプリは一見シンプルに見えますが、質問形式の拡張・リアルタイム集計・認証機能などを追加していくと、本格的な SaaS プロダクトへ発展させることもできます。まずは今回の内容でプロトタイプを作り、実際に使ってもらいながら機能を育てていきましょう。
アプリ開発の基礎から体系的に