LoginSignup
7
5

More than 1 year has passed since last update.

Flutter×Firebase(Crashlytics)でFlutterアプリのエラーやクラッシュ情報を一元管理してみる

Posted at

:book: Flutterの記事を整理し本にしました :book:

  • 本稿の記事を含む様々な記事を体系的に整理し本にまとめました
  • 今後はこちらを最新化するため、最新情報はこちらをご確認ください

まとめ記事

はじめに

Firebaseのクラッシュレポートの統合ソリューション機能を提供するcrashlyticsについて解説します。

Firebase Crashlytics(以下Crashlytics)の概要を確認した上で、アプリのエラー情報を連携する方法を解説します。

概要

Crashlyticsは、アプリで発生した例外やエラーのスタックトレースやログを一元管理するための環境を提供します。

有効化手順

有効化は特段必要ありません。情報が送られると自動で有効化されます。

準備

パッケージのインストール

まずは、必要なパッケージをインストールします。
下記の通り、firebase_crashlyticsのパッケージを入れます。

pubspec.yml
//中略
dependencies:
  flutter:
    sdk: flutter
 firebase_core: ^1.19.1
+ firebase_crashlytics: ^2.8.5
//中略

実装

Crashlyticsは、ログを送信するための仕組みをmainメソッドに設定をし、キャッチされた例外やクラッシュレポートなどを送信します。

ソースコードの全体像は下記のようになります。

main.dart
import 'dart:async';
import 'dart:core';

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

import 'package:firebase_crashlytics/firebase_crashlytics.dart';

void main() async {
  // runZonedGuardedで全体を新しいエラーゾーンを定義
  await runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
    //Flutterでキャッチされた例外/エラー
    FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
    runApp(const MyApp());
  }, (error, stackTrace) {
    //Flutterでキャッチされなかった例外/エラー
    FirebaseCrashlytics.instance.recordError(error, stackTrace);
  });
}

// MyApp,MyHomePageはデフォルトから変更がないため省略

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // 例外を発生させるボタン
            ElevatedButton(
              onPressed: () {
                FirebaseCrashlytics.instance.log('ExceptionLog');
                throw Exception("MyException");
              },
              child: const Text('Throw Error'),
            ),
            // アプリをクラッシュさせるボタン
            ElevatedButton(
              onPressed: () {
                FirebaseCrashlytics.instance.log('CrashLog');
                FirebaseCrashlytics.instance.crash();
              },
              child: const Text('Crash'),
            ),
          ],
        )));
  }
}

サンプルアプリには、例外を発生させるボタンとアプリをクラッシュさせるボタンの2つを作成しています。
例外の方は、シンプルにthrow Exceptionをしているのに対して、クラッシュの方は、FirebaseCrashlytics.instance.crash()で意図的なアプリの停止をしています。

Crashlyticsへのレポートの連携経路は、2種類あります。

  1. Flutterでキャッチされた例外/エラー
    • mainメソッドの中でのFlutterError.onError = FirebaseCrashlytics.instance.recordFlutterErrorで記録
  2. Flutterでキャッチされなかった例外/エラー
    • runZonedGuardedrunAppなどを囲んで新たなエラーゾーンを定義した上で、
      FirebaseCrashlytics.instance.recordErrorで記録

場合によっては、データが送信されるのが、クラッシュ後に再度アプリを立ち上げた時になるので、データが到着していない場合は、再度アプリを起動してください。

動作イメージ

例外のボタンとクラッシュのボタンを押してアプリを停止させます。
その後、再度アプリを立ち上げて、レポートを送信させます。
crashlytics-1.png

続いて、ブラウザからCrashlyticsに行くと、ダッシュボードからそれぞれの詳細を確認できます。
発生させた例外の詳細を確認すると、スタックトレースやログを確認することができます。
crashlytics-2.png
crashlytics-3.png
crashlytics-4.png
crashlytics-5.png

今回はキーについてはデフォルトのまま利用しましたが、カスタムキーを設定することも可能です。
キーを設定することで、問題を分類し、検索などをしやすくできます。

クラッシュレポートの方も、同様に、スタックトレースやログを確認することができます。
crashlytics-6.png

なお、AndroidとiOSは別のアプリなので、問題は別々に管理されるため、表示の切り替えが必要です。
crashlytics-7.png

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5