◉GEMINI LABEN
●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/API / SDK
◈ API / SDK/2026-05-16上級

Firebase Crashlytics のクラッシュログを Gemini API で自動分析した記録 — 個人開発アプリ v2.1.0 での実証

Firebase Crashlytics の生ログを Gemini API に渡して根本原因とコード修正案を自動生成するパイプラインを、個人開発の壁紙アプリ v2.1.0 の実開発で検証した記録です。RecyclerView クラッシュの Before/After 付き。

gemini-api287firebase6crashlyticsandroid8indie-dev23structured-output26python106

✦ プレミアム記事

28日間で50人以上のユーザーが同じクラッシュで落ちていると気づいたのは、Firebase Crashlytics のダッシュボードを眺めていた夜のことでした。

個人で壁紙アプリを開発・運営していると、クラッシュ対応は他の作業に押し出されて後回しになりがちです。壁紙アプリ「Beautiful HD Wallpapers」の Android 版 v2.0.0 をリリースした直後、Crashlytics の Issues タブに java.lang.IndexOutOfBoundsException: Inconsistent detected. Invalid view holder adapter position という行が静かに増えていきました。RecyclerView のアダプターに何かが起きています。でも「何が」おかしいのか、スタックトレースだけでは見えてきませんでした。

この記事は、その問題を Gemini API を使って解析するパイプラインを構築し、実際に根本原因を特定するまでの記録です。コードはすべて動作確認済みです。Firebase Crashlytics REST API と Gemini API を組み合わせた自動分析の仕組みを、最初から作れるようにまとめました。

Crashlytics ダッシュボードの限界と、Gemini に任せた理由

Firebase Crashlytics は優れたツールです。クラッシュの件数、影響ユーザー数、スタックトレース、デバイスモデルと OS バージョンの分布——これらが一箇所に集まります。ただ、「なぜ起きたか」を教えてくれるわけではありません。

RecyclerView の IndexOutOfBoundsException は、特に原因が複数考えられる問題です。データ更新と UI スレッドの非同期競合、notifyDataSetChanged() と個別通知メソッドの混在、メインスレッド外でのデータリスト変更、アダプターが保持するリストと実際のデータの参照が別になっている——どれも「ありうる」原因です。一つひとつ仮説を立てて試すのは時間がかかります。個人開発者にとって、クラッシュ調査に費やす時間はそのまま機会損失につながります。

また、Crashlytics のダッシュボードだけ見ていると、どのクラッシュを最初に修正すべきか優先順位をつけるのも難しいと感じていました。発生回数が多いものが必ずしも最も影響が大きいわけではなく、ユーザーの離脱率に直結しているのは「特定の操作中に落ちるクラッシュ」だったりします。優先順位の判断もある程度自動化できれば、と思っていました。

そこで試みたのが、クラッシュログをそのまま Gemini API に渡して構造化した分析を返してもらう、というアプローチでした。結論から言えば、Gemini 2.5 Pro は最初の試行で「参照の分離(defensive copy の欠如)」を根本原因として挙げ、修正コードの骨格まで提示しました。ダッシュボードを眺めて仮説を立てるよりも、はるかに早く答えに辿り着けました。

Firebase Crashlytics REST API でログを取得する

まず Crashlytics の生ログを自動で取得する仕組みが必要です。Crashlytics はダッシュボード上でしか見られないと思われがちですが、Firebase Admin SDK と REST API を通じてプログラムから取得できます。

Firebase コンソール → プロジェクトの設定 → サービスアカウント → 「Firebase Admin SDK の秘密鍵を生成」で JSON をダウンロードします。このファイルを安全な場所に保管し、GitHub Actions の Secrets に登録します。ローカルに置いたまま git に追加しないよう、.gitignore に必ず記載してください。

from google.oauth2 import service_account
import google.auth.transport.requests
import requests
import json
 
SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
SERVICE_ACCOUNT_FILE = "serviceAccountKey.json"
 
credentials = service_account.Credentials.from_service_account_file(
    SERVICE_ACCOUNT_FILE, scopes=SCOPES
)
 
def get_access_token(credentials) -> str:
    if not credentials.valid:
        credentials.refresh(google.auth.transport.requests.Request())
    return credentials.token

次に Crashlytics REST API でイシューを取得します。フィルタリングのクエリパラメータを活用することで、影響の大きいイシューだけに絞れます。occurrenceCount と affectedUsersCount の両方でフィルタするのが実用的です。件数が多くても影響ユーザーが少ない場合(例: 特定の機種固有のバグ)は後回しにして構いません。

def get_crash_issues(
    project_id: str,
    app_id: str,
    credentials,
    min_occurrence_count: int = 10,
    page_size: int = 20
) -> list[dict]:
    token = get_access_token(credentials)
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }
    url = (
        f"https://firebaseappdistribution.googleapis.com/v1alpha/"
        f"projects/{project_id}/apps/{app_id}/issues"
    )
    params = {
        "pageSize": page_size,
        "filter": f"state=open AND occurrenceCount>={min_occurrence_count}",
        "orderBy": "occurrenceCount desc"
    }
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    return response.json().get("issues", [])
✦

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦Firebase Crashlytics の生ログを Gemini API に渡して根本原因と修正コードを自動生成するパイプラインを、今日から動かせる形で手に入れられる
✦RecyclerView IndexOutOfBoundsException を防御的コピーで根治した実際の Before/After コードと、Gemini 2.5 Pro による原因特定の精度を検証した結果
✦月間 AU 300 万アプリでの本番運用コスト設計と、Flash/Pro の使い分け基準が具体的な数字で分かる
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

◈ API / SDK2026-06-23
Gemini 3.2 Pro の Function Calling を iOS/Android アプリに統合する実装パターン
Gemini 3.2 Pro の Function Calling を iOS/Android アプリに統合する実装ガイド。SwiftUI・Kotlin 両対応の動くコード例と、個人開発の壁紙アプリで実証した本番設計パターン(コスト・レイテンシ・段階ロールアウト・回帰テスト)を解説します。
◈ API / SDK2026-05-16
Gemini Vision で壁紙アプリのカテゴリ自動分類を試した — 精度と落とし穴の実記録
壁紙アプリの画像カテゴリ自動分類を Gemini Vision で実装した記録。精度67%から87%への改善手順と、confidence 閾値で人間レビューを全体の15%に絞り込む運用設計を紹介します。
◈ API / SDK2026-05-15
Gemini API を asyncio で並列化したら、壁紙アプリの多言語説明文生成が12倍速になった
12言語の App Store 説明文生成を Gemini API の asyncio 並列化で13分から65秒に短縮した実装記録です。Semaphore によるレート制限対策と、google-generativeai から google-genai への移行で変わった点まで含めてまとめました。