Skip to content

feat(firebase_crashlytics): rework #3420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
aff7197
Merge pull request #47 from FirebaseExtended/master
Ehesp Jul 30, 2020
0e98060
Merge pull request #48 from FirebaseExtended/master
Ehesp Jul 30, 2020
58c19bf
Merge pull request #54 from FirebaseExtended/master
Ehesp Aug 6, 2020
2f06ff1
Merge branch 'master' of https://github.com/FirebaseExtended/flutterfire
Salakar Aug 13, 2020
bf8339c
Merge branch 'master' of https://github.com/FirebaseExtended/flutterfire
Salakar Aug 25, 2020
90b3f47
Merge branch 'master' of https://github.com/FirebaseExtended/flutterfire
Salakar Aug 27, 2020
4384bdf
feat(firebase_crashlytics): v1 rework (#41)
Ehesp Sep 1, 2020
d42f9fc
fix: add backwards compatible `enableInDevMode` getter/setter (but ma…
Salakar Sep 1, 2020
4b3e109
docs: remove enabledInDevMode docs
Salakar Sep 1, 2020
a769c64
docs: add missing image
Salakar Sep 1, 2020
a2bb740
docs: explicitly mention disabling crashlytics in debug mode
Salakar Sep 1, 2020
b795e0d
fix(ios): cleanup const arguments and prefix names to avoid collisions
Salakar Sep 1, 2020
6960f11
Update packages/firebase_crashlytics/firebase_crashlytics_platform_in…
Salakar Sep 1, 2020
b1d0c53
Update packages/firebase_crashlytics/firebase_crashlytics/example/lib…
Salakar Sep 1, 2020
34da3a7
Update packages/firebase_crashlytics/firebase_crashlytics/example/lib…
Salakar Sep 1, 2020
3f2f530
Update packages/firebase_crashlytics/firebase_crashlytics/example/lib…
Salakar Sep 1, 2020
1c036ed
chore: bump dev versions to dev.2
Salakar Sep 1, 2020
6079359
docs(crashlytics): use sentence casing on titles consistently
Salakar Sep 1, 2020
222a111
docs(crashlytics): update integration steps & code examples
Salakar Sep 1, 2020
469a680
refactor: update example app to use FutureBuilder (#68)
MaikuB Sep 2, 2020
ca49ab5
fix: fix ios logging
Salakar Sep 2, 2020
50798cd
fix(android): keep cosmetic exception class names when obfuscated
Salakar Sep 2, 2020
dd80487
chore: bump version to dev.3
Salakar Sep 2, 2020
d4c7dfc
fix(android): fixed an error when hot restarting (fixes #3432)
Salakar Sep 2, 2020
766406a
fix(ios): hot restart issue on ios (#3432)
Salakar Sep 2, 2020
714ba2a
chore: bump version to dev.4
Salakar Sep 2, 2020
26e7ecc
refactor(example): update android example to flutterEmbedding v2
Salakar Sep 2, 2020
d3f08d7
refactor: fix formatting
Salakar Sep 2, 2020
3a7061f
docs(crashlytics): finalize changelog and add migration guide
Salakar Sep 2, 2020
6543922
docs: fix -> FIX
Salakar Sep 2, 2020
dc921ee
docs: fix -> FIX
Salakar Sep 2, 2020
dfa7f33
docs: capitalize change type on changelog
Salakar Sep 2, 2020
af1ac2f
chore: bump version to dev.5
Salakar Sep 2, 2020
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
62 changes: 62 additions & 0 deletions .github/workflows/firebase_crashlytics.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: firebase_crashlytics

on:
pull_request:
paths:
- "packages/firebase_crashlytics/**"
- ".github/workflows/firebase_crashlytics.yaml"
push:
branches:
- master
paths-ignore:
- "docs/**"

env:
FLUTTERFIRE_PLUGIN_SCOPE: "*firebase_crashlytics*"
FLUTTERFIRE_PLUGIN_SCOPE_EXAMPLE: "*firebase_crashlytics_example*"

jobs:
android:
if: github.event_name == 'pull_request'
runs-on: macos-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 0
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
run: ./.github/workflows/scripts/install-tools.sh
- name: "Build Example"
run: ./.github/workflows/scripts/build-example.sh android
- name: "Drive Example"
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 28
arch: x86_64
target: google_apis
profile: Nexus 5X
script: ./.github/workflows/scripts/drive-example.sh android

apple:
runs-on: macos-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 0
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh dev
- name: "Install Tools"
run: |
./.github/workflows/scripts/install-tools.sh
flutter config --enable-macos-desktop
- name: "Build iOS Example"
run: ./.github/workflows/scripts/build-example.sh ios
- name: "Drive iOS Example"
run: ./.github/workflows/scripts/drive-example.sh ios
- name: "Build MacOS Example"
run: ./.github/workflows/scripts/build-example.sh macos
- name: "Drive MacOS Example"
run: ./.github/workflows/scripts/drive-example.sh macos
Binary file added docs/_assets/crashlytics-example-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_assets/crashlytics-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_assets/crashlytics-filter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 82 additions & 0 deletions docs/crashlytics/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
title: Crashlytics
sidebar_label: Overview
---

## What does it do?

Crashlytics helps you to collect analytics and details about crashes and errors that occur in your app. It does this through three aspects:

- **Logs**: Log events in your app to be sent with the crash report for context if your app crashes.
- **Crash reports**: Every crash is automatically turned into a crash report and sent when the application next opens.
- **Stack traces**: Even when an error is caught and your app recovers, the Dart stack trace can still be sent.

<YouTube id="k_mdNRZzd30"/>

## Installation

### 1. Add dependency

```yaml {5} title="pubspec.yaml"
dependencies:
flutter:
sdk: flutter
firebase_core: "^{{ plugins.firebase_core }}"
Copy link
Contributor

Choose a reason for hiding this comment

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

Haven't been following the updates to firebase_core so I may have missed something but is this step needed as won't it get pulled in as a transitive dependency?

firebase_crashlytics: "^{{ plugins.firebase_crashlytics }}"
```

### 2. Download dependency

```
$ flutter pub get
```

### 3. Platform integration

If you are migrating from a previous version of Crashlytics that used Fabric, please follow these
guides and remove any legacy Fabric integration steps from your project:

- [Android](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=android).
- [iOS/macOS](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=ios).

#### a. Android

1. Add the following classpaths to your `android/build.gradle` file.

```groovy {3} title="android/build.gradle"
dependencies {
// ... other dependencies
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
}
```

2. Apply the following to the bottom of your `android/app/build.gradle` file.

```groovy {5} title="android/app/build.gradle"
dependencies {
// ... your dependencies
}

apply plugin: 'com.google.firebase.crashlytics'
```

#### b. iOS

1. From Xcode select `Runner` from the project navigation.
2. Select the `Build Phases` tab, then click `+ > New Run Script Phase`.
3. Add `${PODS_ROOT}/FirebaseCrashlytics/run` to the `Type a script...` text box.
4. Optionally you can also provide your app's built `Info.plist` location to the build phase's Input Files field:
For example: `$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)`

### 4. Rebuild your app

Once complete, rebuild your Flutter application:

```bash
$ flutter run
```

## Next steps

Once installed, you're ready to start using Firebase Crashlytics in your Flutter Project. View the
[Usage documentation](./usage.mdx) to get started.
63 changes: 63 additions & 0 deletions docs/crashlytics/reports.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
title: Crashlytics in the Firebase Console
sidebar_label: Viewing crash reports
---

## Overview

Once you have Crashlytics setup, you can navigate to Crashlytics in your Firebase Console underneath 'Quality'.
If this page tells you to setup, build or run your app, then you have not correctly setup Crashlytics in your app (see [Usage](usage))

> Crashlytics is enabled by default, to disable it in debug mode (recommended) or for opt-in purposes see [toggle Crashlytics collection.](usage#toggle-crashlytics-collection)

When using any of the examples under [usage](usage), you will be shown a dashboard similar to the following:

![hide:Crashlytics Dashboard Example](crashlytics-example.png)

Here you can see that the crash was ran 4 times in the last 60 minutes.

> Error reports are only uploaded to Crashlytics upon relaunching the app

## Issues

The issues section of the Crashlytics console shows all the reports from your app, and organizes them into separate issues.
One of the issues above originates from `FirebaseCrashlyticsPlugin.java`, which is the module responsible for testing the
Crashlytics [`crash`](usage#forcing-a-crash) method by throwing an uncaught exception to crash the app. Using the [`crash`](usage#forcing-a-crash) method on the same platform
will always add reports to the same issue.

## Filtering crash types

The Crashlytics console allows you to filter your issues by event types such as `Crashes` and `Non-fatals`.
In the below example, you can see our project filtered by `Non-fatal` crashes.

![hide:Crashlytics Filter Example](crashlytics-filter.png)

In the issues section, it shows us that the event was triggered in the `mobile.dart` file on line 62, which is the below
code snippet:

```dart highlight={2} title="mobile.dart"
try {
throw 'error_example';
} catch (e, s) {
FirebaseCrashlytics.instance.recordError(e, s, context: 'as an example');
}
```

## Managing issues

By clicking on an issue, you can view its statistics and associated reports in more detail. The below screenshot shows the
issue relating to `FirebaseCrashlyticsPlugin.java`

![hide:Crashlytics Issue Example](crashlytics-example-detail.png)

Here you can see a breakdown of the issue, that shows events by versions, devices and operating systems. Below that, you
can browser specific reports and view their content. In our example, you can see that we have used the [`setCustomKey`](usage#add-custom-keys) method
to add in our custom attributes. Under the log section, you can see any messages added by the [`log`](usage#add-custom-log-messages') method

## Closing issues

At the top right of the issue, there is a button that says "Close." After addressing the issue, you can close it, allowing
you to filter this out on the dashboard. When the same issue re-occurs, it will automatically open again. If you want to
prevent this from happening, click the drop down arrow next to the button and select mute.


170 changes: 168 additions & 2 deletions docs/crashlytics/usage.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,172 @@
---
title: Crashlytics
title: Using Firebase Crashlytics
sidebar_label: Usage
---

Crashlytics usage
To start using Firebase Crashlytics within your project, import it at the top of your project files:

```dart
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
```

## Sending reports to Crashlytics

To send report data to Crashlytics, the **application must be restarted**. Crashlytics automatically sends any crash reports
to Firebase the next time the application is launched.

## Toggle Crashlytics collection

Call the `setCrashlyticsCollectionEnabled` method to toggle Crashlytics collection status.

For example to ensure it is disabled when your app is in debug mode you can do the following:

```dart
import 'package:flutter/foundation.dart' show kDebugMode;

// ...

if (kDebugMode) {
// Force disable Crashlytics collection while doing every day development.
// Temporarily toggle this to true if you want to test crash reporting in your app.
await FirebaseCrashlytics.instance
.setCrashlyticsCollectionEnabled(false);
} else {
// Handle Crashlytics enabled status when not in Debug,
// e.g. allow your users to opt-in to crash reporting.
}
```

You can additionally read the current collection enabled status:

```dart
if (FirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled) {
// Collection is enabled.
}
```

## Forcing a crash

You don't have to wait for a crash to know that Crashlytics is working. To force a crash, call the `crash` method:

```dart
FirebaseCrashlytics.instance.crash();
```

Your app should exit immediately after calling this method. After opening your app again after the crash
Firebase Crashlytics will upload the crash report to the Firebase Console.

The error will be show on the Firebase Crashlytics dashboard as an instance of `FirebaseCrashlyticsTestCrash`, with a message of
`This is a test crash caused by calling .crash() in Dart.`

## Add custom keys

To associate key/value pairs with your crash reports, you can use the `setCustomKey` method

```dart
// Set a key to a string.
FirebaseCrashlytics.instance.setCustomKey('str_key', 'hello');

// Set a key to a boolean.
FirebaseCrashlytics.instance.setCustomKey("bool_key", true);

// Set a key to an int.
FirebaseCrashlytics.instance.setCustomKey("int_key", 1);

// Set a key to a long.
FirebaseCrashlytics.instance.setCustomKey("int_key", 1L);

// Set a key to a float.
FirebaseCrashlytics.instance.setCustomKey("float_key", 1.0f);

// Set a key to a double.
FirebaseCrashlytics.instance.setCustomKey("double_key", 1.0);
```

> This accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or values that exceed 1024 characters are truncated.

## Add custom log messages

To add custom Crashlytics log messages to your app, use the `log` method

```dart
FirebaseCrashlytics.instance.log("Higgs-Boson detected! Bailing out");
```

## Set user identifiers

To add user IDs to your reports, assign each user with a unique ID. This can be an ID number, token or hashed value:

```dart
FirebaseCrashlytics.instance.setUserIdentifier("12345");
```

## Handling uncaught errors

By overriding `FlutterError.onError` with `FirebaseCrashlytics.instance.recordFlutterError`, it will automatically
catch all errors that are thrown within the Flutter framework.

```dart
void main() {
// Pass all uncaught errors from the framework to Crashlytics.
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;

runApp(MyApp());
}
```
### Zoned Errors

If you want to catch errors that occur in zones, you can pass `FirebaseCrashlytics.instance.recordError` to the second
parameter of `runZonedGuarded`

```dart
runZonedGuarded<Future<void>>(() async {
// ...
}, FirebaseCrashlytics.instance.recordError);
```

### Errors outside of Flutter

To catch errors that happen outside of the Flutter context, install an error listener on the current Isolate:

```dart
Isolate.current.addErrorListener(RawReceivePort((pair) async {
final List<dynamic> errorAndStacktrace = pair;
await FirebaseCrashlytics.instance.recordError(
errorAndStacktrace.first,
errorAndStacktrace.last,
);
}).sendPort);
```

## Enable opt-in reporting

By default, Crashlytics will automatically collect crash reports for all your app's users. To give users more control over
the data they send, you can enable opt-in reporting by disabling automatic collection and initializing Crashlytics only for selected users:

1. Turn off automatic collection natively:

a. Android
In the `application` block of your `AndroidManifest.xml` file, add a `meta-data` tags to turn off automatic collection:

```xml
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
```

b. iOS

Add a new key to your `Info.plist` file.

- Key: `FirebaseCrashlyticsCollectionEnabled`
- Value: `false`

2. Enable collection for select users by calling the Crashlytics data collection override at runtime. To opt out of automatic
crash reporting, pass `false` as the override value. When set to `false`, the new value does not apply until the next run
of the app.

```dart
FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
```


Loading