◉ANTIGRAVITY LABJP
Articles/App Development
▣ App Development/2026-05-04Intermediate

Automating Firebase Crashlytics Analysis with Antigravity

Use Antigravity to automate Firebase Crashlytics crash analysis. Covers BigQuery export setup, AI-powered root cause detection, and a GitHub Actions workflow for daily mobile crash reporting.

firebase11crashlytics5ios38android30mobile-devcrash-analysisgithub-actions9

✦ Premium Article

Every Monday morning, the first tab I open is Crashlytics. And every Monday morning, the count is higher than it was on Friday.

If you're maintaining a mobile app solo, crash report triage is the kind of work that quietly piles up while you're focused on shipping features. Reading stack traces one by one, trying to reproduce, patching, repeat — it's draining in a way that's hard to explain until you've lived it.

I started using Antigravity to handle this differently. Instead of manually reading Crashlytics reports, I now pull the data via BigQuery, feed the structured crash context into Antigravity, and let it scan the codebase to pinpoint which method is responsible. This article walks through the exact workflow.

Setting Up Crashlytics BigQuery Export

Before anything else, enable the Crashlytics BigQuery export in your Firebase Console under Crashlytics → BigQuery export. Once enabled, crash events start flowing into a firebase_crashlytics dataset in BigQuery automatically.

Note: it takes 24–48 hours for the first data to appear after enabling. If you haven't set this up yet, do it now — it's a one-time configuration.

With the export running, here's a Python script to fetch your top 10 fatal crashes from the last 7 days:

# crash_fetcher.py
from google.cloud import bigquery
from datetime import datetime, timedelta
 
def get_top_crashes(project_id: str, app_id: str, days: int = 7) -> list[dict]:
    """
    Fetch the top 10 fatal crashes from Crashlytics via BigQuery.
 
    Prerequisites:
    - Firebase Crashlytics BigQuery export enabled
    - google-cloud-bigquery installed: pip install google-cloud-bigquery
    - GCP auth set up: gcloud auth application-default login
 
    Args:
        project_id: Your Firebase project ID (e.g., "my-app-12345")
        app_id: Your Firebase App ID from Project Settings > General
                Format: "1:123456789012:ios:abcdef1234567890"
        days: Number of days to look back (default 7)
    """
    client = bigquery.Client(project=project_id)
 
    # BigQuery table names replace ":" in app_id with "_"
    table_id = app_id.replace(":", "_")
    table = f"{project_id}.firebase_crashlytics.{table_id}"
 
    query = f"""
    SELECT
        issue_id,
        issue_title,
        issue_subtitle,
        COUNT(*) AS crash_count,
        ARRAY_AGG(
            STRUCT(
                application.display_version AS version,
                device.manufacturer AS manufacturer,
                device.model AS model,
                os.display_version AS os_version,
                ARRAY(
                    SELECT CONCAT(frame.file, ':', CAST(frame.line AS STRING))
                    FROM UNNEST(exceptions[OFFSET(0)].frames) AS frame
                    WHERE frame.file IS NOT NULL
                    LIMIT 10
                ) AS stack_frames
            )
            ORDER BY event_timestamp DESC
            LIMIT 3
        ) AS recent_examples
    FROM `{table}*`
    WHERE
        _TABLE_SUFFIX BETWEEN
            FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL {days} DAY))
            AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
        AND is_fatal = TRUE
    GROUP BY issue_id, issue_title, issue_subtitle
    ORDER BY crash_count DESC
    LIMIT 10
    """
 
    results = client.query(query).result()
    return [dict(row) for row in results]
 
 
if __name__ == "__main__":
    crashes = get_top_crashes(
        project_id="your-firebase-project-id",
        app_id="1:000000000000:ios:aaaaaaaaaaaaaaaa"
    )
    for crash in crashes:
        print(f"[{crash['crash_count']} crashes] {crash['issue_title']}")
    # Example output:
    # [247 crashes] Fatal Exception: NSInvalidArgumentException
    # [89 crashes] Fatal Exception: EXC_BAD_ACCESS SIGSEGV

Formatting Crash Data for Antigravity

The key insight here is that dumping raw crash output into Antigravity doesn't work as well as you'd hope. What actually helps is giving Antigravity a structured prompt that includes crash frequency, device context, and specific questions to answer.

# crash_analyzer.py
from crash_fetcher import get_top_crashes
 
def format_crash_for_ai(crash: dict) -> str:
    """
    Format a Crashlytics crash report as a structured Antigravity prompt.
 
    Adding frequency counts, device info, and explicit questions
    significantly improves Antigravity's analysis accuracy.
    Tested with NSInvalidArgumentException, EXC_BAD_ACCESS, NSRangeException.
    """
    examples = crash.get("recent_examples", [])
 
    # Collect unique device/OS combinations
    devices = list({
        f"{ex['manufacturer']} {ex['model']} (OS {ex['os_version']})"
        for ex in examples
        if ex.get("manufacturer")
    })[:3]
 
    # Stack frames from the most recent crash
    stack_frames = []
    if examples and examples[0].get("stack_frames"):
        stack_frames = examples[0]["stack_frames"]
 
    prompt = f"""
## Crashlytics Crash Analysis Request
 
**Occurrences (last 7 days):** {crash['crash_count']}
**Error type:** {crash['issue_title']}
**Subtitle:** {crash.get('issue_subtitle', 'N/A')}
**Primary devices affected:** {', '.join(devices) if devices else 'Unknown'}
 
**Stack trace (most recent crash, top 10 frames):**
{chr(10).join(f'  {i+1}. {frame}' for i, frame in enumerate(stack_frames))}
 
**Please:**
1. Identify the most likely root cause based on the stack trace
2. Point to the specific file(s) and method(s) in the codebase to investigate
3. Suggest three fixes in priority order
4. Estimate the minimal reproduction steps
"""
    return prompt
 
 
if __name__ == "__main__":
    crashes = get_top_crashes("your-firebase-project-id", "1:000000000000:ios:aaaaaaaaaaaaaaaa")
 
    # Output top 3 crashes as Antigravity prompts
    for i, crash in enumerate(crashes[:3], 1):
        print(f"\n{'=' * 60}\n### Crash #{i}")
        print(format_crash_for_ai(crash))

Paste the output into Antigravity's chat, and it will scan your codebase for relevant files before generating the analysis.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Triage crashes by real user impact (deduplicated installation_uuid), not raw count
✦Ready-to-use code to format both iOS and Android stack traces before handing them to Antigravity
✦Measured crash-free-rate and turnaround gains, plus three pitfalls of AI crash analysis
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

▣ App Dev2026-05-24
Running iOS Push Notification A/B Tests Weekly With Antigravity Agent — A Self-Improving Loop For Copy, Timing, And Segments
Drawing on years of indie iOS development across wallpaper and wellness apps, this article walks through a weekly Push Notification A/B loop powered by Antigravity Agent — the FCM bridge, BigQuery measurement, segment design, a D7 retention recovery story, and a dependency-free simulation that made me cut the number of arms and add a significance rule before declaring any winner.
▣ App Dev2026-04-19
Building a Fully Automated iOS App Release Pipeline with Antigravity — From Screenshot Generation to App Store Review Management
Use Antigravity, App Store Connect API, and GitHub Actions to automate every step from build to App Store submission. A complete advanced guide covering AI screenshot captions, metadata optimization, and rejection analysis.
▣ App Dev2026-04-03
Antigravity × Capacitor Hybrid App Implementation Guide: An AI-Driven Workflow for Taking a Web App to iOS/Android Native
Implementation notes for taking an existing web app to iOS/Android with Capacitor and Antigravity, drawn from running indie apps. Covers native API integration, AdMob initialization order, launch-time white flash, and pre-submission checks, separating what is verified from what is not.