Firebase Realtime Database とは? Rork との相性を理解する
アプリに「リアルタイムにデータが更新される体験」を加えたいと思ったことはありませんか。チャット・ライブスコア・共同編集・在庫管理など、複数のユーザーが同じデータをリアルタイムで共有するユースケースは非常に多く存在します。
Firebase Realtime Database は、Google が提供するクラウドホスト型の NoSQL データベースです。最大の特徴はデータの変化をミリ秒単位でクライアントにプッシュするリアルタイム同期機能で、WebSocket ベースの常時接続によりサーバーへのポーリングなしに即座にデータを取得できます。
Rork はアプリのコード生成に React Native(Expo)を使用しているため、Firebase JavaScript SDK を自然な形で組み込めます。データベース操作のコードは Rork のプロンプトで生成・修正できるため、Firebase の知識がゼロでも段階的に学びながら実装を進められます。
ここでは Firebase プロジェクトのセットアップから Rork アプリへの SDK 組み込み、リアルタイムリスナーの実装、オフライン対応まで、必要なステップをすべて解説します。
Firebase プロジェクトのセットアップ
Firebase コンソールでプロジェクトを作成する
- Firebase コンソール にアクセスし、「プロジェクトを作成」をクリックします。
- プロジェクト名(例:
my-rork-app)を入力し、Google Analytics の設定を行って「プロジェクトを作成」をクリックします。 - 作成後、左メニューの「構築」→「Realtime Database」を選択します。
- 「データベースを作成」をクリックし、リージョン(日本向けには
asia-southeast1またはus-central1)を選びます。 - セキュリティルールは開発中は「テストモード」を選択します(本番前に必ず変更すること)。
iOS・Android アプリを Firebase に登録する
- Firebase コンソールのプロジェクト概要から「アプリを追加」→「iOS」または「Android」を選択します。
- iOS: バンドル ID(例:
com.yourname.myapp)を入力し、GoogleService-Info.plistをダウンロードします。 - Android: パッケージ名(例:
com.yourname.myapp)を入力し、google-services.jsonをダウンロードします。 - ダウンロードしたファイルは Rork プロジェクト内の適切な場所(通常はルートまたは
assets/フォルダ)に配置します。
Rork アプリへの Firebase SDK 組み込み
必要なパッケージのインストール
Rork のプロンプトに次のように入力して、Firebase SDK のインストールと初期化コードを生成してもらいましょう。
Firebase Realtime Database を使うために、以下のパッケージをインストールして
初期化コードを追加してください:
- @react-native-firebase/app
- @react-native-firebase/database
Firebase の設定値(apiKey, databaseURL 等)は環境変数から読み込む形にしてください。
または、Firebase JavaScript SDK(Web 版)を使う方法もあります。React Native 環境でも動作し、Expo managed workflow でも扱いやすいのが特徴です。
# Expo プロジェクトでの Firebase Web SDK インストール
npx expo install firebaseFirebase の初期化(firebase.ts)
プロジェクトのルートに firebase.ts(または src/lib/firebase.ts)を作成します。
// src/lib/firebase.ts
import { initializeApp, getApps, getApp } from 'firebase/app';
import { getDatabase } from 'firebase/database';
// Firebase の設定値(Firebase コンソール → プロジェクトの設定 → マイアプリ から取得)
const firebaseConfig = {
apiKey: process.env.EXPO_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.EXPO_PUBLIC_FIREBASE_DATABASE_URL, // ← 必須
projectId: process.env.EXPO_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.EXPO_PUBLIC_FIREBASE_APP_ID,
};
// アプリを二重初期化しないためのガード
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApp();
const database = getDatabase(app);
export { app, database };設定値は .env.local ファイルに保存し、Git にコミットしないよう .gitignore に追加しましょう。APIキーはコード中に直接記載せず、必ず YOUR_API_KEY のようなプレースホルダーかプロセス環境変数で管理する点が肝心です。
データの読み書き:CRUD 操作の実装
Firebase Realtime Database では、データを JSON ツリーとして管理します。パス(/todos/item1 のような文字列)でデータの場所を指定してアクセスします。
データの書き込み(set / push)
// src/hooks/useFirebaseData.ts
import { database } from '../lib/firebase';
import { ref, set, push, remove, update } from 'firebase/database';
// 特定のパスにデータをセット(上書き)
export const setData = async (path: string, data: object) => {
const dataRef = ref(database, path);
await set(dataRef, data);
};
// リストに新しいアイテムを追加(自動IDを生成)
export const addItem = async (path: string, data: object) => {
const listRef = ref(database, path);
const newItemRef = push(listRef); // 自動で一意のIDを生成
await set(newItemRef, {
...data,
createdAt: Date.now(), // タイムスタンプを追加
});
return newItemRef.key; // 生成されたIDを返す
};
// アイテムを削除
export const deleteItem = async (path: string) => {
const itemRef = ref(database, path);
await remove(itemRef);
};
// アイテムを部分更新
export const updateItem = async (path: string, updates: object) => {
const itemRef = ref(database, path);
await update(itemRef, updates);
};リアルタイムリスナーで変更を購読する
Firebase Realtime Database の最大の強みが、データ変更を即座に受信できる「リスナー」機能です。onValue を使えば、他のユーザーが行ったデータ変更が自動的に UI に反映されます。
// src/hooks/useRealtimeList.ts
import { useEffect, useState } from 'react';
import { database } from '../lib/firebase';
import { ref, onValue, off } from 'firebase/database';
interface Item {
id: string;
text: string;
completed: boolean;
createdAt: number;
}
export const useRealtimeList = (path: string) => {
const [items, setItems] = useState<Item[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const dataRef = ref(database, path);
// onValue でリアルタイムリスナーを登録
const unsubscribe = onValue(
dataRef,
(snapshot) => {
const data = snapshot.val();
if (data) {
// オブジェクトを配列に変換(Firebaseはオブジェクト形式でデータを返す)
const list = Object.entries(data).map(([id, value]) => ({
id,
...(value as Omit<Item, 'id'>),
}));
// 作成日時でソート
list.sort((a, b) => a.createdAt - b.createdAt);
setItems(list);
} else {
setItems([]); // データが空の場合
}
setLoading(false);
},
(err) => {
setError(err.message);
setLoading(false);
}
);
// クリーンアップ:コンポーネントのアンマウント時にリスナーを解除
return () => off(dataRef);
}, [path]);
return { items, loading, error };
};リアルタイム TODO リストの実装例
上記のフックを使ったシンプルな TODO リストコンポーネントです。
// src/components/RealtimeTodoList.tsx
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, FlatList, StyleSheet } from 'react-native';
import { useRealtimeList } from '../hooks/useRealtimeList';
import { addItem, deleteItem, updateItem } from '../hooks/useFirebaseData';
const TODO_PATH = 'todos'; // Firebase の /todos パスを使用
export const RealtimeTodoList: React.FC = () => {
const [inputText, setInputText] = useState('');
const { items, loading } = useRealtimeList(TODO_PATH);
const handleAdd = async () => {
if (!inputText.trim()) return;
await addItem(TODO_PATH, {
text: inputText.trim(),
completed: false,
});
setInputText('');
};
const handleToggle = async (id: string, completed: boolean) => {
await updateItem(`${TODO_PATH}/${id}`, { completed: !completed });
};
const handleDelete = async (id: string) => {
await deleteItem(`${TODO_PATH}/${id}`);
};
if (loading) return <Text>読み込み中...</Text>;
return (
<View style={styles.container}>
<View style={styles.inputRow}>
<TextInput
style={styles.input}
value={inputText}
onChangeText={setInputText}
placeholder="タスクを入力..."
/>
<TouchableOpacity style={styles.addButton} onPress={handleAdd}>
<Text style={styles.addButtonText}>追加</Text>
</TouchableOpacity>
</View>
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.item}>
<TouchableOpacity onPress={() => handleToggle(item.id, item.completed)}>
<Text style={item.completed ? styles.completedText : styles.itemText}>
{item.completed ? '✅ ' : '⬜ '}{item.text}
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => handleDelete(item.id)}>
<Text style={styles.deleteButton}>🗑</Text>
</TouchableOpacity>
</View>
)}
/>
</View>
);
};このコンポーネントを 2 台のデバイスで開くと、片方でタスクを追加・完了した瞬間、もう一方の画面にもリアルタイムで反映されます。これが Firebase Realtime Database の醍醐味です。
セキュリティルールの設定(本番前に必須)
開発中のテストモードはセキュリティが無効化されています。本番リリース前に必ず適切なルールを設定してください。
// Firebase コンソール → Realtime Database → ルール
{
"rules": {
"todos": {
"$uid": {
// 各ユーザーは自分のデータのみ読み書き可能
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}ユーザー認証との組み合わせについては、Rork でユーザー認証を実装する — Firebase・Supabase 連携ガイド も参照してください。
オフライン対応の設定
Firebase Realtime Database は、デバイスがオフラインの状態でも動作できる設定があります。一度取得したデータをローカルにキャッシュし、再接続時に自動同期します。
// src/lib/firebase.ts に追記
import { getDatabase, enableLogging } from 'firebase/database';
// オフラインキャッシュを有効化(アプリ起動時に一度だけ呼び出す)
// ※ React Native Firebase を使用する場合のみ利用可能
// Web SDK の場合は goOffline / goOnline で手動制御
// 接続状態の監視
import { ref, onValue } from 'firebase/database';
export const monitorConnection = (onConnected: () => void, onDisconnected: () => void) => {
const connectedRef = ref(database, '.info/connected');
onValue(connectedRef, (snap) => {
if (snap.val() === true) {
onConnected();
} else {
onDisconnected();
}
});
};.info/connected という特別なパスを監視することで、接続状態をリアルタイムに把握できます。オフライン時にはローカルへの書き込みをキューに積み、オンラインに戻ったタイミングで自動的に Firebase へ送信されます。
なお、バックエンドの選択については Rork アプリの外部 API 連携ガイド で全体的な方針も確認できます。
全体を振り返って
ここではRork アプリに Firebase Realtime Database を組み込む手順を解説しました。
Firebase プロジェクトのセットアップから SDK の初期化、onValue を使ったリアルタイムリスナーの実装、CRUD 操作、セキュリティルールの設定、オフライン対応まで、一通りの流れを理解いただけたかと思います。
特にポイントとなるのは「一度のデータ変更が即座にすべての接続デバイスに反映される」という体験で、これを実現するコードは驚くほどシンプルです。Rork のプロンプトにこの記事のコードスニペットを貼り付けて「このパターンを参考に実装して」と指示するだけで、Firebase 連携のベースが完成します。
さらにリアルタイムチャットや複数ユーザーによる共同編集など、より高度な実装に挑戦したい方には、Rork でリアルタイムチャットアプリを構築する — Supabase 認証・リアルタイム DB・プッシュ通知の完全実装ガイド がおすすめです。Firebase とは異なるアーキテクチャから得られる学びも多く、バックエンド選択の視野が広がります。
Firebase × Rork の組み合わせで、ぜひ魅力的なリアルタイムアプリを作り上げてください。