AIにコードを書いてもらってWebアプリを作る、というやり方が現実的になってきました。
私も今、MedTimerというお薬タイマーのWebアプリをClaude Codeで作っています。
アプリそのものの話は、開発ブログのほうに書いています。

コードはAIが書いてくれます。ここは本当に速いです。
でも、「服薬履歴を残したいのでデータベースを使いたい」となったとき、詰まりました。
AIから返ってきたのは、こういう案内でした。
Firebase 設定がなくてもアプリはローカル保存モードで完全に動作します。
同期を有効にする手順:
- Firebase コンソールでプロジェクトを作成
- Authentication → Sign-in method → Google を有効化
- Firestore Database を作成(本番モード)
- ルールに firestore.rules の内容を貼り付けて公開
- プロジェクトの設定 → マイアプリ → Webアプリを追加し、構成値を取得
- .env.example を .env にコピーして値を記入
コードを書くところはAIがやってくれても、Firebaseコンソールの画面をクリックするのは自分です。
ここはAIが代わりにやってくれない部分でした。
プロジェクトの作成まではできたのですが、その次の
「Authentication → Sign-in method → Google を有効化」
で、そもそもAuthenticationがどこにあるのかわからず止まりました。
同じところで止まる人が絶対にいると思ったので、私がやった手順をそのまま残しておきます。
- そもそもFirebaseとは何なのか
- 前提:Firebaseは無料枠のまま使えます
- 【手順0】Firebase コンソールでプロジェクト作成
- 【手順1】Authentication → Googleログインを有効化
- 【手順2】Firestore Databaseを作成する
そもそもFirebaseとは何なのか
手順の前に、Firebaseが何をしてくれるものなのかを整理しておきます。
私も最初は「データベースの名前」くらいの認識でしたが、実際は少し違いました。
Firebaseは、Googleが提供している「アプリの裏側」をまとめて借りられるサービスです。
アプリには、画面に見えている部分と、見えていない部分があります。
見えている部分(ボタンや文字)は、AIに書いてもらったコードがブラウザの中で動かしてくれます。
でも「昨日の服薬記録を、明日もう一度アプリを開いたときに表示する」となると、データをどこかに保管しておく場所が要ります。
さらに「これは私の記録で、他人の記録ではない」と区別するには、ログインのしくみも要ります。
本来なら、この保管場所とログインのしくみを、自分でサーバーを借りて作る必要があります。
Firebaseは、そこをまるごと肩代わりしてくれるものです。
今回使うのは2つだけ
Firebaseにはたくさんの機能がありますが、今回のお薬タイマーで使うのはこの2つです。
この2つがそろって初めて、「自分のスマホでもパソコンでも、同じ服薬履歴が見られる」という状態になります。
逆に言うと、Firebaseを設定しなくてもアプリ自体は動きます。
ただしその場合、データはブラウザの中だけに保存されるので、別の端末では見られませんし、ブラウザのデータを消すと履歴も消えます。
私が今回Firebaseを入れることにしたのは、この「消えたら困る」を避けたかったからです。
前提:Firebaseは無料枠のまま使えます
最初に不安なところを潰しておきます。
Firebaseの無料プランはSparkプランという名前です。
Firestore(データベース)については、
1日あたり50,000回の読み取り・20,000回の書き込み・ストレージ1GBまでが無料
とされています(2026年7月時点)。
個人が自分の服薬記録を残す程度の使い方であれば、この枠を超える気配はありません。
クレジットカードの登録も不要です。
【手順0】Firebase コンソールでプロジェクト作成
① Firebaseコンソールにアクセス
そうすると下記の画像のような画面になります。

② プロジェクト名を入力
私は自分のアプリ名「MedTimer」としました。

③ 概要ページが表示される

【手順1】Authentication → Googleログインを有効化
①「セキュリティ」→「Authentication」→ 初回は「始める」というボタンが出る
押すとSign-in methodの設定画面に進みます。

Firebaseコンソールの左メニューを見ると、「Database と Storage」「セキュリティ」「AI サービス」「Hosting とサーバーレス」といったカテゴリが並んでいます。
データベースの話だから「Database と Storage」だろうと思って開くと、Authenticationは出てきません。
Authenticationは「セキュリティ」の中にあります。
ここが最初のつまずきポイントでした。
ログイン機能=データベース、というイメージで探していたので、しばらく見つけられませんでした。
② プロバイダの一覧から「Google」を選択して、右上のトグルをON


2つ入力を求められます。
- プロジェクトの公開名:ログイン画面に表示される名前です。アプリ名でかまいません
- プロジェクトのサポートメール:プルダウンから自分のGoogleアカウントを選ぶだけです
「保存」を押して、Googleの行が「有効」になれば完了です。
【手順2】Firestore Databaseを作成する
① 左メニューの「Database と Storage」→「Firestore」

②「データベースの作成」をクリック

③ 下記画面が出てくるため「Standardエディション」を選択(詳細は👇)

Standardエディション? Enterpriseエディション?
「エディションを選択」という項目が出てきて、また手が止まりました。
StandardとEnterpriseの2つがあり、名前だけ見るとEnterpriseのほうが高機能そうです。
調べた範囲では、個人アプリならStandardで問題ありません。
Enterpriseエディションは2026年1月に登場した新しいもので、MongoDB互換のAPIが使えたり、Pipeline operationsという高度なクエリ機能が使えたりするものです。Firebaseの公式ドキュメントでは、Standardは「基本的な読み取り・書き込み・クエリ」に対応した通常版、Enterpriseは高度なクエリエンジンを備えた版、と説明されています。
Enterpriseにも無料枠はあるので「選んだら課金される」わけではないのですが、インデックスを自分で管理する必要が出てきたり、リアルタイムリスナーの一部機能に制限があったりと、初心者が触るには扱いが増えます。
AIが書いてくれるコードも、基本的にStandardの通常の書き方を前提にしています。
迷ったらStandard。これで大丈夫でした。
④ ロケーション(サーバーの場所)を選択(asia-northeast1(東京)など)

ここはあとから変更できないと説明されているので、少し慎重に選ぶ場所です。
⑤ 構成では「本番環境モード」を選ぶ

テストモードだと誰でもデータを読み書きできてしまう状態になり、しかも一定期間を過ぎると読み書きできなくなります。
本番モードを選ぶと最初は誰も書き込めない状態になりますが、次の手順でルールを入れれば動くようになります。
【手順3】セキュリティルールを貼り付ける
① Firestoreの画面上部にある「ルール」タブを開く

エディタが出てきます。

② AIが生成してくれた firestore.rules というファイルの中身をまるごと貼り付けて、「公開」
このルールが「ログインした本人のデータだけ、本人が読み書きできる」という条件を決めている部分です。
ここを設定しないままにしておくと、データが全世界に開放されるか、逆に自分すら書き込めないかのどちらかになります。
firestore.rules には何が書いてあるのか
AIが作ってくれたので私は貼り付けただけですが、中身を見ないままにしておくのも気持ち悪いので、何が書いてあるのか調べました。
基本の形はこうです。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// users/{userId} 以下は、その本人だけが読み書きできる
match /users/{userId}/{document=**} {
allow read, write: if request.auth != null
&& request.auth.uid == userId;
}
}
}
読み方を分解すると、こうなります。
request.auth != null:ログインしている人だけ許可。ログインしていない人は全部拒否request.auth.uid == userId:ログイン中の人のIDと、アクセスしようとしているパスのIDが一致するときだけ許可{document=**}:そのフォルダ配下すべてに同じルールを適用
つまり users/自分のID/ の中には、自分でログインした人しか触れない、という設定です。
ルールはデータの置き方とセットで決まる
ここが重要なところなのですが、ルールだけを先に書くことはできません。
上のルールが成立するのは、コードが「ユーザーIDごとにフォルダを分けて」データを保存している場合です。
users/
└ abc123/ ← ログインしたユーザーのID
└ medications/
└ (服薬記録)
もしコードが別の置き方をしていて、記録を1か所にまとめて保存し、各データに「これは誰のものか」を書き込む設計なら、ルールの書き方も変わります。
match /medications/{docId} {
allow read, update, delete: if request.auth != null
&& request.auth.uid == resource.data.userId;
allow create: if request.auth != null
&& request.auth.uid == request.resource.data.userId;
}
新規作成のときはデータがまだ存在しないので resource ではなく request.resource を見る、という違いがあります。
自分で書く場合は、先にコードを見て、データがどのパスに保存されるかを確認してからルールを書くことになります。
コードの中の collection(...) や doc(...) に渡しているパスが、そのままルールに書くパスです。
書かなかった場所は自動的に拒否される
ルールに書いていないパスは、すべて拒否されます。
「書き忘れて全世界に開放されてしまう」ということは起きません。
逆に言うと、「動かない」ときはまずルールを疑うことになります。
ルールが正しいか確かめる場所がある
Firestoreの「ルール」タブには、Rules Playground(ルールプレイグラウンド)という試験用の画面があります。
操作の種類(読み取り/作成/更新/削除)、パス、ログイン状態を指定して実行すると、そのルールで許可されるか拒否されるかが表示されます。
他人のIDを入れたときにちゃんと拒否されるか、ここで確認できます。
これは本番で使ってはいけない書き方です。
allow read, write: if true;
誰でも自由に読み書きできる状態になります。テストモードで作成すると、これに近いものが入っています。
【手順4】Webアプリを追加して構成値を取得
① プロジェクトの概要画面に戻り、「+ アプリを追加」をクリック

② iOS / Android / Web などのアイコンが並ぶので、Web(</> のマーク)を選ぶ

③ アプリのニックネーム:自由(MedTimer Web など)
「Firebase Hosting も設定する」のチェックは外したままでOK(あとから使えます)

④ 「アプリを登録」を押すと、こういうコードが表示される👇
const firebaseConfig = {
apiKey: "AIzaSy...",
authDomain: "medtimer-xxxxx.firebaseapp.com",
projectId: "medtimer-xxxxx",
storageBucket: "medtimer-xxxxx.firebasestorage.app",
messagingSenderId: "123456789012",
appId: "1:123456789012:web:abcdef..."
};
※この画面を閉じてしまっても大丈夫です。
設定(歯車アイコン)→ プロジェクトの設定 → マイアプリから、いつでも見返せます。
画面の説明
①「npmを使用する」と「<script>タグを使用する」の違い
この画面には切り替えタブがあって、どちらを選べばいいのか迷いました。
これはFirebaseを読み込む方法の違いだということです。
- npm:プロジェクトのフォルダにFirebaseの部品を入れて、コードから
importして使う方法。ViteやReactなど、ビルドツールを使う構成向け - <script>タグ:HTMLファイルに直接、外部から読み込む方法。ビルドなしの素のHTML向け
AIが .env ファイルを使う前提でコードを書いてくれているなら、それはビルドツールを使う構成です。
その場合はnpmのほうを見ればいいことになります。
② npm install firebase はやらなくていいのか
画面には npm install firebase というコマンドもコピーできる形で載っています。
ここで、「AIがもうやってくれているのか、自分でやる必要があるのか」がわからなくなりました。
確認方法があります。
ターミナルでプロジェクトのフォルダに移動して、こう打ちます。
cat package.json | grep firebase
"firebase": "^11.x.x" のような行が出てくれば、すでにインストール済みです。
何も出てこなければ、npm install firebase を実行します。
AIに任せていると「どこまでやってもらったか」が自分でも把握できなくなりがちなので、こういう確認コマンドを1つ知っておくと安心できると思います。
③ 表示されている初期化コードは貼らなくていいのか
構成値の下には、こういうコードも一緒に表示されます。
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
これも「どこかに貼らないといけないのかな」と思ったのですが、すでにAIが同じことをやっているファイルがプロジェクト内にあるはずです。
確認するには、ターミナルでこう打ちます。
grep -r "initializeApp" src/
出てきたファイル(src/firebase.js など)を開いて、firebaseConfig の中身が import.meta.env.VITE_FIREBASE_API_KEY のような書き方になっていれば、あとは .env に値を書くだけです。
なお getAnalytics の行はアクセス解析を使うときのもので、お薬タイマーには必要ありませんでした。
【手順5】.env ファイルに値を書く
ここからはVSCode(エディタ)側の作業です。
① AIが .env.example というお手本ファイルを作ってくれている場合は、それをコピー
cp .env.example .env
② できた .env を開いて、手順4でコピーした値を書き込む
VITE_FIREBASE_API_KEY=AIzaSy...
VITE_FIREBASE_AUTH_DOMAIN=medtimer-xxxxx.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=medtimer-xxxxx
VITE_FIREBASE_STORAGE_BUCKET=medtimer-xxxxx.firebasestorage.app
VITE_FIREBASE_MESSAGING_SENDER_ID=123456789012
VITE_FIREBASE_APP_ID=1:123456789012:web:abcdef...
ダブルクォート(")で囲む必要はありません
変数名は .env.example に書かれているものに必ず合わせます。ここが1文字違うだけで読み込まれません。
.env を書いたら、開発サーバーを一度止めて起動し直します。
.env は起動したときにしか読み込まれないので、書いただけでは反映されません。
これで反映されてればOK!
【落とし穴】公開したらGoogleログインができなくなった
ここまでの手順で、localhost(自分のパソコンの中)ではGoogleログインが動きました。
Firestoreにもデータが保存されて、これで完成だと思いました。
安心してサーバーにアップロードして、公開したURLを開いて、Googleログインのボタンを押したら――
ログインできませんでした。
コードは何も変えていません。localhostでは動いていたものを、そのまま上げただけです。
結論から書くと、Firebaseの「承認済みドメイン」に自分のドメインを追加していなかったのが原因でした。
なぜlocalhostでは動いたのか
これまでにやってきた設定(プロジェクト作成、Googleログインの有効化、.envへの値の記入)は、
「ログイン機能そのものを使えるようにする」
ための設定でした。
それとは別に、Firebaseは「どのサイトからのログインを受け付けるか」を許可制にしています。
そして、初期状態で許可されているのは localhost と、Firebaseが用意したドメインだけです。
つまり、開発中は最初から許可リストに入っているので何もしなくても動きます。
ところが本番のドメイン(私の場合は medtimer.fanelab.com)は許可リストに入っていないので、そこからのログイン要求は拒否される、という状態になっていました。
「localhostで動いたから大丈夫」と思い込んでいたので、原因にたどり着くまで少し時間がかかりました。
これは意地悪な仕様ではなく、守るための仕組み
調べてわかったのですが、これはなりすまし対策です。
Firebaseの構成値(apiKey など)は、以前の記事で書いたとおり、ブラウザに配信される公開情報です。
つまり、その気になれば誰でもコピーできます。
もしドメインの制限がなかったら、悪意のある人が私の構成値をコピーして偽サイトを作り、そこでGoogleログインさせることができてしまいます。
「どのドメインからなら受け付けるか」を私自身が指定しておくことで、そういう偽サイトからのログインを弾いています。
公開情報である apiKey がそれほど危険ではない理由の一つが、ここにもありました。
【手順6】(ドメインを決めたら)承認済みドメインに追加する手順
やることは1つだけです。
Firebaseコンソールで「Authentication」を開きます(手順1で行った、左メニューの「セキュリティ」の中です)。
そこにある「設定」タブを開くと、「承認済みドメイン」という項目があります。
初期状態では、こういうものが並んでいるはずです。
localhostプロジェクト名.firebaseapp.comプロジェクト名.web.app
ここに「ドメインを追加」ボタンがあるので、自分が公開したドメインを入力します。
medtimer.fanelab.com
https:// は不要です。ドメイン部分だけを入れます。
追加したら、公開したサイトを開き直して、Googleログインを試します。
私はこれで通りました。
入力するのはドメインだけ
OK:medtimer.fanelab.com
NG:https://medtimer.fanelab.com/(プロトコルやスラッシュは不要)
Vercelなどにデプロイした場合
独自ドメインではなく、Vercelなどが自動で発行するURLを使っている場合も同じです。
その場合は、発行されたドメイン(アプリ名.vercel.app のような形)を追加します。
プレビュー用のURLが毎回変わる構成だと、そのたびに追加が必要になることもあります。
エラーメッセージから見つける場合
もしブラウザの開発者ツール(コンソール)を見られる状態なら、こういうエラーが出ているはずです。
Firebase: Error (auth/unauthorized-domain)
unauthorized-domain、つまり「許可されていないドメイン」と、そのまま書いてあります。
Firebaseのログイン系のトラブルでこのエラーが出たら、承認済みドメインを疑うのが最短だと思います。
公開するときの決まりごととして覚えておく
この設定は、Firebaseでサイトを公開するときの毎回のお約束にあたります。
本番ドメインを決めたら、承認済みドメインに追加する。
Firebaseの設定は、コンソールを開いて選択して保存して、を何度も繰り返します。
一つひとつは難しくないのですが、「どれか一つ抜けているだけで動かない」という性質があります。
しかも今回のように、開発中はまったく問題なく動いてしまうので、抜けていることに気づけません。
公開してから慌てることになりました。
Firebaseを使ったアプリを公開する予定があるなら、デプロイする前に承認済みドメインを見ておくと、私と同じ焦り方をせずに済むと思います。
apiKeyをAIに見せていいのか、GitHubに上げてはいけないのか
ここが個人的に一番気になった部分でした。
「APIキー」という名前が付いていると、絶対に人に見せてはいけないもののように感じます。
AIにコードを見せている状態で大丈夫なのか、Claude Codeの設定で .env を読ませないようにすべきなのか、悩みました。
調べた範囲では、FirebaseのWeb用 apiKey は、そもそもブラウザに配信される公開情報です。
パスワードのような秘密の鍵ではなく、「どのFirebaseプロジェクトに接続するか」を示す識別子にあたります。
実際にデータを守っているのは、手順1で設定したAuthentication(誰がログインしているか)と、手順3で貼り付けたセキュリティルール(誰が何を読み書きできるか)のほうです。
なので、AIに見られて即座に危険、というものではありませんでした。
とはいえ、.gitignore に .env を入れておく習慣は持っておいて損はないと思います。
確認するにはこう打ちます。
cat .gitignore | grep env
.env という行が出てくれば設定済みです。出てこなければ、.gitignore を開いて .env と1行書き足します。
gitignoreについては別の記事でも紹介しているので使い方がわからない方はご参照ください!

本当に隠すべきなのは別のもの
Firebaseまわりで絶対に公開してはいけないのは、サーバー側で使う鍵のほうです。
Firebase Admin SDKのサービスアカウントJSONファイルなどがそれにあたります。こちらは公開されると、ルールを無視してデータベースを操作されてしまいます。
Web用のapiKeyとは、危険度がまったく違います。
この区別を知らないと、「公開して大丈夫なもの」に怯えて、「本当に危ないもの」を気づかず置いてしまう、ということが起きそうです。
どうしてもAIに .env を読ませたくない場合は、Claude Codeならプロジェクト直下の .claude/settings.json にこう書く方法があります。
{
"permissions": {
"deny": ["Read(./.env)"]
}
}
詳しい書き方については別の記事をご参照ください👇

ただしこれを入れると、AIが .env の中身を見て「値の書き間違いがある」と教えてくれることもできなくなります。
私は今回、Web用のapiKeyしか入れていないので、この設定はしていません。
つまずいた場所のまとめ
まとめ
AIにコードを書いてもらうと、コードは動くのに、その手前の「設定」で止まるという状況が起きます。
Firebaseコンソールをクリックするのも、ロケーションを選ぶのも、.env に値を貼るのも、結局は自分の手でやることです。
しかも、AIが出してくれる手順書は「Authentication → Sign-in method → Google を有効化」のように、すでにFirebaseを知っている人向けの粒度で書かれていることが多いです。
知らない人にとっては、その1行の中に3回くらい迷子になるポイントが埋まっています。
私は今回、その1行1行がわからなくてAIに質問を投げ続けました。それで通せました。
コードが書けないからアプリが作れない、という時代ではなくなってきましたが、「わからないところをそのまま聞ける」というのは、それ自体がひとつの進め方なんだと思います。
MedTimerの中身については、開発ブログのほうで書いています。



