Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions skills/firebase-crashlytics-basics/SKILL.md
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we removed the other skills:

description: Comprehensive guide for accessing Firebase Crashlytics crash reports. Use this skill when the user needs to debug issues using crash data.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: firebase-crashlytics-basics
description: Comprehensive guide for Firebase Crashlytics, including SDK setup, instrumentation, and accessing crash reports. Use this skill when the user needs to instrument their mobile application, configure advanced reporting, or debug issues using crash data.
compatibility: This skill is best used with the Firebase CLI, but does not require it. Install it by running `npm install -g firebase-tools`.
---

# Firebase Crashlytics

This skill provides resources for integrating Firebase Crashlytics in Android applications and accessing crash reports.

## Data & Reporting

Access crash reports and manage issues directly through the MCP server:

* **Reports**: [reports.md](references/reports.md)
* **Issues**: [issues.md](references/issues.md)
* **Investigations**: [investigations.md](references/investigations.md)
56 changes: 56 additions & 0 deletions skills/firebase-crashlytics-basics/references/investigations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
### How to Diagnose and Fix Crashlytics Issues

Follow these steps to diagnose bugs and and propose fixes for issues.

1. Make sure you have a good understanding of the code structure and where different functionality exists. If technical documentation exists in the code base, read it first.
2. Use the `crashlytics_get_issue` tool to get more context on the issue.
3. Use the `crashlytics_batch_get_events` tool to get an example crash for this issue. Use the event names in the sampleEvent fields.
3a. If you need to read more events, use the `crashlytics_list_events` tool.
3b. Apply the same filtering criteria that you used to find the issue, so that you find appropriate events.
4. Read the files that exist in the stack trace of the issue to understand the crash deeply.
5. Determine possible root causes for the crash - no more than 5 potential root causes.
6. Critique your own determination, analyzing how plausible each scenario is given the crash details.
7. Choose the most likely root cause given your analysis.
8. Create a plan for the most likely root cause using the following format for the plan:

```
## Cause

<A description of the root cause leading to the issue>
- **Fault**: <a determination of whether this code base is at fault or a dependent library is at fault>
- **Complexity**: <one of "simple", "moderately simple", "moderately hard", "hard", "oof, I don't know where to start">

## Fix

<A description of the fix for this issue and a break down of the changes.>
1. <Step 1>
2. <Step 2>

## Test

<A plan for how to test that the issue has been fixed and protect against regressions>
1. <Test case 1>
2. <Test case 2>

## Other potential causes

1. <Another possible root cause>
2. <Another possible root cause>
```

9. If there is not enough information in the crash report to find a root cause, describe why you cannot fix the issue instead of making a guess.

### Special Investigations

#### Analyzing NDK (Native) Crashes
Native crashes often look intimidating but follow predictable patterns.
* **Signal 11 (SIGSEGV):** Segmentation violation. Usually a null pointer dereference (`*ptr = 0`) or accessing freed memory (Use-after-free).
* **Signal 6 (SIGABRT):** Abort. The app deliberately killed itself, often because of an unhandled C++ exception or a failed assertion (`assert(condition)`).
* **Missing Symbols:** If the stack trace shows `(missing)` or hex addresses (e.g., `0x000532`), you cannot debug it. Check if `nativeSymbolUploadEnabled` is on and if the correct mappings were uploaded.

#### Analyzing ANRs (Application Not Responding)
* **The "Main" Culprit:** Look immediately at the thread named `main`. This is the UI thread.
* **Blocked vs. Busy:**
* *Blocked:* The main thread is waiting on a lock (monitor contention) held by another thread. Look for "Waiting to lock..." in the stack trace, then find the thread holding that lock.
* *Busy:* The main thread is doing too much work (e.g., heavy JSON parsing, sorting a huge list, image processing) directly on the UI thread.
* **Deadlocks:** If Thread A holds Lock 1 and wants Lock 2, while Thread B holds Lock 2 and wants Lock 1, nobody moves.
51 changes: 51 additions & 0 deletions skills/firebase-crashlytics-basics/references/issues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Understanding Crashlytics Issues

This guide details the structure and lifecycle of a Crashlytics "Issue". Understanding these concepts is critical for effectively prioritizing and communicating stability problems to the user.

## 1. The Anatomy of an Issue

In Crashlytics, similar crashes are grouped together into an **Issue**. This grouping is done automatically on the server side unless you encounter a unique scenario where custom grouping is required (rare).

### Key Components

* **Issue ID (UUID):** A hexadecimal string (e.g., `5b34...`) that uniquely identifies the issue group.
* **Title:** usually the Exception Type (e.g., `java.lang.NullPointerException` or `SIGSEGV`).
* **Subtitle:** usually the top frame of the stack trace that is "blamed" for the crash (e.g., `com.example.app.MainActivity.onCreate`).
* **Variant:** Different "flavors" of the same root cause. For example, the same crash might happen on two different lines or have slightly different stack traces but share the same root cause.

## 2. Issue Types (Fatalities)

Crashlytics categorizes issues into three primary bucket types. You can look for these in the `issueErrorTypes` filter.

1. **FATAL (Crashes):** The app completely terminated. These are the highest severity as they disrupt the user experience entirely.
* *Examples:* Uncaught Kotlin/Java exceptions, Native (C++) crashes (SIGSEGV, SIGABRT).

2. **NON_FATAL (Logged Errors):** The app caught an exception but decided to report it (using `FirebaseCrashlytics.getInstance().recordException(e)`). The user might have seen an error dialog or a silent failure, but the app remained open.

3. **ANR (Application Not Responding):** The UI thread was blocked for too long (5+ seconds), and the OS prompted the user to close the app.
* *Note:* ANRs are particularly damaging to Google Play Store rankings (`bad behavior threshold`).

## 3. Issue Signals

Crashlytics assigns "Signals" to help with triage.

* **EARLY:** The first time this crash has been seen in a *new* version of the app. Useful for spotting regressions in a staged rollout.
* **FRESH:** A completely new crash that has never been seen before in *any* version.
* **REGRESSED:** A crash that was previously marked "Closed" but has reappeared in a new app version. This indicates a failed fix or a re-introduction of the bug.
* **REPETITIVE:** A crash that is happening frequently to a single user.

## 4. Prioritization Strategy

When presenting issues to a user or deciding what to fix, use this hierarchy:

1. **Impacted Users (Reach):** Always prioritize issues affecting the *highest number of distinct users* over raw event counts. A crash hitting 1,000 users once is worse than a crash hitting 1 user 1,000 times.
2. **Velocity:** Issues that are spiking recently (e.g., "Velocity Alert") take precedence.
3. **Severity:** FATAL/ANR > NON_FATAL.

## 5. Working with Issues

When using the `crashlytics_update_issue` tool:

* **OPEN:** The default state. The issue is active and needs attention.
* **CLOSED:** The issue has been fixed. If it occurs again in a *new* version, it will regress.
* **MUTED:** The issue is known but "won't fix" or is noise. It will not alert you again unless you unmute it.
79 changes: 79 additions & 0 deletions skills/firebase-crashlytics-basics/references/reports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Crashlytics Reports

Aggregate metrics for all of the events sent to Crashlytics are available as reports.
The following reports are available for all Crashlytics applications.

- `topIssues`<br>
Counts events and distinct impacted users, grouped by issue. Issue groups are sorted by event count, in descending order.

- `topVariants`<br>
Counts events and distinct impacted users, grouped by issue variant. Issue variant groups are sorted by event count, in descending order.<br>
required: An issue filter including an issue id is required.

- `topVersions`<br>
Counts events, grouped by app version. Versions are sorted by event count, in descending order.

- `topOperatingSystems`<br>
Counts events, grouped by device operating systems and their versions. Operating systems are sorted by event count, in descending order.

Mobile apps have one of the following reports available, depending on the platform.

- `topAndroidDevices`<br>
Counts events, grouped by android device. Devices are sorted by event count, in descending order.

- `topAppleDevices`<br>
Counts events, grouped by operating system and Apple device. Devices are sorted by event count, in descending order.

Report responses contain the following metrics:

- `eventsCount`: the number of events matching
- `impactedUsers`: the number of distinct end users in all the matching events

Report responses are always grouped by one of the following dimensions:

- app version
- issue
- variant
- operating system
- mobile device type

## Filters

When setting report filters adhere to the following instructions.

* Issue Filtering:
* Use the `issueErrorTypes` field to focus on events of different fatalities:
* `FATAL`: native crashes, which caused the app to exit.
* `NON_FATAL`: uncaught or manually reported exceptions, which did not crash the app.
* `ANR`: "app not responding" events, only relevant on Android platforms.
* Add an `issueId` filter to narrow any report to a specific issue.

* Time Interval:
* For a custom time range, you must specify both `intervalStartTime` and `intervalEndTime`.
* The specified time range must be within the last 90 days.
* If you don't provide a time range, it will default to the last 7 days.

* Display Names (for app versions, operating systems, and devices):
* The values for `versionDisplayNames`, `operatingSystemDisplayNames`, and `deviceDisplayNames` must be obtained from the `displayName` field of a previous API response.
* These display names must match specific formats:
* Device: 'manufacturer (device)'
* Operating System: 'os (version)'
* App Version: 'version (build)'

## Useful Reports

* The `topIssues` report is comparable to the default view on the Crashlytics web dashboard. Use this report first to prioritize which issues are impacting the most users. Apply appropriate filters for time interval based on the user's query.

* Report responses grouped by issue will include a sample event URI. Use the `crashlytics_batch_get_events` tool to fetch the complete record for any sample event.

* When investigating an issue, use the appropriate top devices and top operating systems reports to understand what systems are impacted by the problem. Pass the `issueId` in the filter to narrow any report to a specific issue.

## How to Display Issues

When displaying a list of issues, use the following format:
```
1. Issue <full issue id>
* <the issue title>
* <the issue subtitle>
* **Description:** <a description of the issue based on information from the tool response>
```