課題
AIと一緒に個人開発しているスマホアプリを、App Storeに5本出している。どのアプリにも、利用状況を記録するFirebase Analyticsと、アプリが落ちたときの情報を集めるFirebase Crashlyticsを入れていた。
入れていた、つもりだった。
公開から30日たったアプリの数字を振り返ったところ、iOSからはFirebaseにデータが届いていなかった。調べると、原因は5本とも同じ。早いものは公開から約1か月、その状態のまま動いていた。
さらに困ったことに、約2か月前に書いた自分たちの教訓集には「iOSは問題なし」と書いてあった。
解決できるようにすること
「設定ファイルは置いた」「ライブラリは入れた」という状態と、「データが実際に届いている」状態は別物。この差を、自分のアプリで確かめられるようにする。
特に、初期化に失敗してもアプリが落ちずに動き続ける作りにしている場合、その失敗にどこで気づくかを持ち帰れるようにする。
先に結論
原因は、iOS用の設定ファイルGoogleService-Info.plistが、フォルダには置いてあったのに、Xcodeのターゲットに登録されていなかったこと。ターゲットは、どのファイルをアプリに詰めるかなどを決めるビルドの設定のこと。ファイルはプロジェクトのフォルダにあるのに、できあがったアプリの中には入っていなかった。
そのせいで、iOSではFirebaseの初期化が失敗していた。でもアプリ側は、失敗を警告ログに出すだけで、何事もなかったように動き続ける作りになっていた。だから約1か月、誰も気づかなかった。
気づけたきっかけは、App Store側の数字とFirebaseの数字を並べたこと。App Storeにはセッションの記録があるのに、FirebaseのiOSのアクティブユーザーは0だった。
この記事でわかること
- iOSでFirebaseの設定ファイルが「あるのに読まれない」仕組みと、その確かめ方
- 初期化の失敗を握りつぶす作りが、何を隠してしまうか
- ストアの数字と分析ツールの数字を突き合わせて、計測漏れに気づく方法
- 教訓を書き残しても、予防策が「検討する」で止まっていると同じ型の漏れを防げなかった実例
こう思う人もいるかもしれない。
「フォルダにファイルがあるなら、アプリにも入っているんじゃないの?」
iOSでは、そうとは限らない。Flutterが作るような従来型のXcodeプロジェクトでは、フォルダに置いただけのファイルはアプリにコピーされない。ターゲットに登録したファイルだけが、アプリの中に入る。フォルダにあることと、アプリに入っていることは、別の話だった。
2か月前の教訓集には「iOSは問題なし」と書いてあった
話は8月の初めにさかのぼる。最初のアプリをストアへ出す準備をしていたとき、5本ともAndroid版のFirebase設定ファイルが無いことが分かった。このときの記録には、iOS版は設定ファイルを正しく用意済みなので対象外、iOSは問題なし、と書いてある。
この件は、リリース準備で踏んだ落とし穴をまとめた教訓集にも載せた。予防策として書いたのは次の2つ。
- AndroidとiOSの両方で、設定ファイルが実際に置かれているかをセルフチェックする
- Analyticsのデータが実際にFirebaseへ届いているかを、一度は実機で確認するチェック項目を入れることを「検討する」
1つ目は、iOSでは何の問題もなくクリアできてしまう。ファイル自体は置いてあったから。
今回の漏れを見つけられたのは2つ目のほう。でも語尾は「検討する」のままだった。Android版を直したときの記録でも、実機やエミュレータでデータが届くかの確認は「未実施」と書かれていた。
このときの話は、以前にアプリの本番リリース直前、なぜ『動いているのに』設定漏れで止まるのか?という記事にも書いた。その記事では、Firebaseの設定ファイルが「5本のアプリ全部でAndroid側だけ用意されていなかった」と書いている。iOS側は大丈夫、という前提で書いていたことになる。
今回分かったのは、その前提が間違っていたということ。iOS側も、別の形でちゃんと動いていなかった。
30日の振り返りで、ストアとFirebaseの数字が合わなかった
10月6日、公開から30日たったアプリの振り返りを、AIに進めてもらった。AIがApp Store Connect(Appleの開発者向け管理画面)とFirebaseの画面を読み取って、数字を並べていった。
最初に引っかかったのは、鉱石がテーマのパズルアプリの振り返り。クラッシュの状況を見ようとFirebase Crashlyticsを開くと、iOSアプリは「SDKの追加」という表示のままだった。一度も接続を受け取っていない状態。Android版のほうは「アプリが検出され、クラッシュを待機しています」と出ているのに。
続けて、ポーション作りがテーマのパズルアプリの振り返りをすると、今度はFirebase AnalyticsでiOSのアクティブユーザーが、30日・7日・1日のどれも0だった。
一方、App Store Connectのほうには、同じ期間のセッションが記録されている。App Store Connectの数字は、データの共有に同意した人の分だけなので、もともと小さい。それでも0ではない。
片方に記録があって、もう片方が0。こうなったら「使われていない」ではなく「計測できていない」を疑うことになる。
ちなみに、先に振り返った鉱石パズルのほうでは、Firebaseのアクティブユーザーに小さな数字が出ていて、それをそのまま記録していた。後から見直すと、これはiOSの利用者の数字ではなく、開発用のAndroid端末なども含めたプロジェクト全体の数字だった可能性が高い(ここは確かめていない)。0ではない数字が出ていると、それだけで「動いている」ように見えてしまう。
原因は、ファイルが「置いてあるだけ」だったこと
AIがプロジェクトを調べると、5本ともXcodeのプロジェクト設定ファイル(project.pbxproj)の中に、GoogleService-Info.plistへの参照が1件も無かった。ファイルはios/Runner/フォルダにある。でもターゲットには登録されていない。だから、できあがったアプリにはコピーされていなかった。
iOS対応の準備手順書を見ても、「Firebaseの管理画面からGoogleService-Info.plistをダウンロードしてios/Runner/に置く」までしか書いていなかった。ターゲットに登録するという一手が、手順ごと抜けていた。
もう一つ背景がある。自分の開発用のMacにはXcodeが入っていない。iOSのビルドはずっと、クラウドのビルドサービス(Codemagic)に任せてきた。ビルドは通るし、TestFlight(Appleのテスト配信の仕組み)にも上がるし、ストアの審査も通って公開できた。設定ファイルがアプリに入っていなくても、途中のどこでも止まらなかった。

「落ちない作り」が、失敗を約1か月隠していた
設定ファイルがアプリに入っていないと、iOSではFirebaseの初期化が失敗する。ここで効いてきたのが、全アプリ共通の分析の仕組みの作り。初期化に失敗しても、警告をログに出すだけで、分析なしのまま動き続けるようにしてあった。
この作り自体は、8月の教訓集でも「正しい判断」と書いていた。分析ツールの不調でアプリが落ちたら、使っている人に迷惑がかかる。
でも裏返すと、失敗したことがどこにも表に出てこない。誰もそのログを見なければ、失敗は無かったのと同じになってしまう。
しかも、この副作用は8月の時点で分かっていた。Android版の設定漏れが表に出なかったのも、まったく同じ理由だったから。それでもiOSで同じ形の漏れが残ったのは、予防策が「ファイルがあるか」の確認止まりで、「データが届いたか」の確認が「検討する」のまま残っていたから、という形になる。
もう一つ、Crashlyticsは「入っている」だけだった
調べる中で、別の漏れも見つかった。Crashlyticsのライブラリは、依存関係にはちゃんと入っていた。ところが、アプリの中で起きたエラーをCrashlyticsへ送る処理が、どのアプリのコードにも1つも無かった。こっちはiOSだけでなく、Androidも含めた話になる。
公開後に見る数字をまとめた表には「Crashlytics 全アプリ導入済み」と書いてあった。でも「導入済み」の中身は、ライブラリを入れたところまで。エラーを送るところまでは届いていなかった。
FlutterでCrashlyticsを使う場合、ライブラリを入れるだけでは、Flutter側で起きたエラーは送られない。FlutterError.onError(Flutterの処理中に起きたエラーの受け口)とPlatformDispatcher.instance.onError(それ以外の非同期処理などのエラーの受け口)を、Crashlyticsの記録処理へつなぐ必要がある。
直して、TestFlightで「届いた」ことを確かめた
直したのは次の2つ。
- 5本の
project.pbxprojに、GoogleService-Info.plistをアプリにコピーするファイルとして登録した - 全アプリ共通の分析の仕組みに、エラーをCrashlyticsへ送る処理を足した。開発中のDebugビルドでは送らないようにした
Xcodeが無いので、1はXcodeの画面からではなく、AIがproject.pbxprojを直接書き換える方法を自分が選んだ。登録に必要だったのは4か所。ファイルの参照、ビルド用の項目、Runnerグループの中身、リソースをコピーする手順の中身。書き換えた後は、Mac標準のplutilというコマンドで、ファイルの構文と参照のつながりが壊れていないかを確かめた。
2は、Firebaseの初期化に成功したときだけ組み込む形にした。初期化に失敗したときは、これまでどおり分析なしで動き続ける。「落ちない作り」はそのまま残したことになる。
確認は、集中タイマーアプリの修正版をCodemagicでビルドしてTestFlightに上げ、自分のiPhoneで起動して行った。起動した直後にAIがFirebaseの画面を見ると、Analyticsの過去30分のグラフにバーが立って、上位の国に「Japan 1」が出た。CrashlyticsのiOSアプリも、「SDKの追加」から「アプリが検出され、クラッシュを待機しています」に変わった。
過去30日・7日・1日の数字は0のまま。iOSからこれまで届いていなかったことと、修正が効くことが、同時に確かめられた形になる。
公開中の5本には、それぞれ次のアップデートで同じ修正を届けることにした。この修正だけのために審査へ出すことはしない、と自分で決めた。アップデートを公開したら、FirebaseでiOSの接続を確かめて記録するところまでを1セットにする。準備手順書にも「置くだけでは足りない。ターゲットへの登録が必要」と書き足した。
自分のアプリで確かめる手順
Firebaseを使っているiOSアプリなら、次の順で確かめられる。上ほど手軽。
- プロジェクト設定に参照があるか: ターミナルで
grep -c "GoogleService-Info.plist" ios/Runner.xcodeproj/project.pbxprojを実行する。0なら、ターゲットに登録されていない。登録されていれば、ファイルの参照・ビルド用の項目・グループ・リソースをコピーする手順の中に名前が出てくる(自分が直したときに足したのも、この4か所) - Xcodeがあるなら画面で見る:
GoogleService-Info.plistを選んで、右側のインスペクタの「Target Membership」でRunnerにチェックが入っているかを見る。または、Runnerターゲットの「Build Phases」→「Copy Bundle Resources」に入っているかを見る。自分はXcodeが無いので、この方法は使っていない - できあがったアプリの中身を見る: ビルドしてできた
Runner.appの中にGoogleService-Info.plistがあるかを見る。自分は環境の都合で、この確認はしていない - データが届いているかを見る: テスト配信版を実機で起動して、Firebase Analyticsの過去30分の表示に利用者が出るかを見る。Crashlyticsで、iOSアプリが「SDKの追加」のままになっていないかも見る
- ストアの数字と並べる: 公開後は、App Store Connectのセッションなどの数字と、FirebaseのiOSのアクティブユーザーを並べる。ストアに記録があって分析側が0なら、計測漏れを疑う。プロジェクト全体の合計だけを見ていると、Android側の数字に紛れて見落とすので、iOSとAndroidを分けて見る
もう一つ。初期化に失敗しても動き続ける作りにしているなら、その失敗を「どこで知るか」を先に決めておきたい。ログに出すだけだと、誰も見なければ無いのと同じになる。自分の場合は、上の4のように、公開後にFirebaseでiOSの接続を確かめて記録する手順で補うことにした。
こんな人に向いている
FlutterなどでiOSアプリを作っていて、FirebaseのAnalyticsやCrashlyticsを入れている人に向いている。特に、Xcodeをあまり開かずに、クラウドのビルドサービスでiOS版を作っている人には、他人事ではないはず。
ほかにも、「エラーで落とさない」作りを選んだことがある人や、教訓やチェックリストを書き残しているのに同じ種類の漏れが起きる人には、予防策の書き方を見直すきっかけになると思う。
まとめ
ファイルを置いた、ライブラリを入れた、管理画面で有効にした。どれも「作業した」という事実ではあっても、「データが届いている」ことの確認にはならなかった。今回は、ストアの数字とFirebaseの数字を並べたことで、やっとその差が見えた。
| 項目 | 内容 |
|---|---|
| 結論 | GoogleService-Info.plistがフォルダにあってもXcodeのターゲットに未登録だとアプリに入らず、初期化の失敗を握りつぶす作りのせいで、iOSのFirebaseが約1か月動いていないことに気づかなかった |
| 教訓 | 「ファイルがある」ではなく「データが届いた」で確かめる。予防策を「検討する」で止めない。ストアの数字と分析ツールの数字をプラットフォーム別に突き合わせる |
| 対象読者 | FirebaseをiOSアプリに入れている人、Xcodeをあまり開かずにiOS版をビルドしている人、教訓を書き残しても同じ型の漏れが起きる人 |
同じ状況に陥ったときの回避策
project.pbxprojにGoogleService-Info.plistの参照があるかを、grepで確かめる。0件ならターゲットに入っていない- 設定を入れたら、テスト配信版を実機で起動して、Firebaseのリアルタイム表示とCrashlyticsの接続状態で「届いた」ことまで見る
- Crashlyticsは、ライブラリを入れるだけでなく、
FlutterError.onErrorとPlatformDispatcher.instance.onErrorを記録処理へつないであるかを確かめる - 公開後は、ストアのセッションなどの数字と、分析ツールのiOS・Android別の数字を並べる。片方だけ0なら計測漏れを疑う
- 初期化の失敗を握りつぶす作りにするなら、その失敗をどこで知るかを一緒に決める
- 教訓集の予防策は「検討する」で終わらせず、いつ・誰が・何を見て確かめるかまで書く。「ファイルが置いてあるか」のような確認は、別の形の漏れを素通りさせることがある
次に読むなら
設定ファイルがアプリに入っていると確かめられたら、その受け皿になる計測の仕組みそのものが有効になっているかも見ておくと安心できる。
- 計測タグを実装していたのに、5本のアプリすべてで計測が始まっていなかった話 — Firebaseの管理画面でGoogle Analytics自体が有効になっているかを確かめる手順と、5本まとめて見直した記録
この記事は、筆者が個人で開発しているモバイルアプリの開発記録(2026年8月2日〜10月6日)を基に、独自調整したAIが下書きを作成し、筆者が事実確認・編集を行った上で公開しています。

