🔥
【初心者向け】Firebase Crashlyticsが正常に動いているか確認する手順
こんにちは、ワニかず@40歳 出戻りエンジニアです。
FlutterでFirebase Crashlyticsにエラーの情報が表示されるよう
コードを用意したものの、正常に動いているのかどうかを確認するのに
少し時間がかかりましたので、その確認方法をまとめました。
前提
- FlutterのアプリとFirebaseの疎通が取れていること(FirestoreやAuthenticationなどで)
クラッシュが起きる前の状態
以下のように、左側のメニューから「Crashlytics」を選択すると、
まだ何も起きていないので、
「クラッシュを待機しています。」
と記載されており、何も表示されていません。
一生待機していたほしい(一生クラッシュしないでほしい)
と誰しも思うと思うのですが、
いざクラッシュしたときに、何も追跡できないと大変なので、
ちゃんとクラッシュした情報がここの表示されるか確認します。
実装したコード
- app_logger.dart
app_logger.dart
import 'package:flutter/foundation.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_core/firebase_core.dart';
class AppLogger {
static bool _initialized = false;
// ログレベル定義
static const int DEBUG = 0;
static const int INFO = 1;
static const int WARNING = 2;
static const int ERROR = 3;
static int currentLevel = kDebugMode ? DEBUG : INFO;
// Crashlyticsの初期化
static Future<void> initialize() async {
if (_initialized) return;
// Firebaseが初期化されていることを確認
if (Firebase.apps.isEmpty) {
await Firebase.initializeApp();
}
// Flutterのエラーを自動的にCrashlyticsに送信する
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
// 非同期エラーをキャッチするためのハンドラも設定できます
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
_initialized = true;
i('AppLogger initialized with Crashlytics');
}
// 以下、従来のログメソッド
static void d(String message) {
_ensureInitialized();
if (currentLevel <= DEBUG) {
print('🔍 DEBUG: $message');
}
}
static void i(String message) {
_ensureInitialized();
if (currentLevel <= INFO) {
print('ℹ️ INFO: $message');
FirebaseCrashlytics.instance.log(message);
}
}
static void w(String message) {
_ensureInitialized();
if (currentLevel <= WARNING) {
print('⚠️ WARNING: $message');
FirebaseCrashlytics.instance.log('WARNING: $message');
}
}
static void e(String message, [dynamic error, StackTrace? stackTrace]) {
_ensureInitialized();
if (currentLevel <= ERROR) {
print('🔴 ERROR: $message');
if (error != null) {
print(error);
if (stackTrace != null) {
FirebaseCrashlytics.instance.recordError(error, stackTrace);
}
} else {
FirebaseCrashlytics.instance.log('ERROR: $message');
}
}
}
// 初期化されていることを確認する内部メソッド
static void _ensureInitialized() {
if (!_initialized) {
print('⚠️ AppLogger used before initialization. Call AppLogger.initialize() first.');
// 非同期で初期化を試みる
initialize();
}
}
// その他のメソッド...
}
- main.dart
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await AppLogger.initialize();
// その他の初期化処理
runApp(MyApp());
}
- pubspec.yaml
pubspec.yaml
dependencies:
flutter:
sdk: flutter
firebase_core: ^latest_version
firebase_crashlytics: ^latest_version # この行を追加
# 他の依存関係...
latest_version
の部分は、最新のバージョン番号(例: ^4.3.4
)に置き換えてください。
Crashlyticsの動作確認方法
非致命的エラーを記録してテストする
main.dart
に、
main.dart
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await AppLogger.initialize();
try {
throw Exception('これはテストエラーです');
} catch (e, stack) {
// ここが実行されるのを確認する
FirebaseCrashlytics.instance.recordError(e, stack, reason: 'テスト目的');
}
runApp(MyApp());
}
クラッシュが検知されると?
以下のような画面になります。
CrashlyticsとAnalyticsの使い分け
Crashlytics
- 主な目的: アプリのクラッシュや深刻なエラーを検出し、診断情報を提供する
-
メリット:
- クラッシュの原因を特定しやすい
- スタックトレースや発生状況の詳細を提供
- 開発者視点でのアプリ安定性の把握に最適
- 実装の優先度: 安定性が重視されるアプリでは高い
Analytics
- 主な目的: ユーザー行動や使用パターンを追跡し、アプリのパフォーマンスを分析
-
メリット:
- ユーザーの行動パターンを把握できる
- コンバージョンや目標達成率を測定できる
- ビジネス/マーケティング視点での指標取得に最適
- 実装の優先度: ユーザー行動の分析が重視されるアプリでは高い
選択の基準
-
アプリの現状:
- アプリが不安定でクラッシュが頻繁に発生する場合 → Crashlyticsを優先
- アプリの使用状況や行動パターンを理解したい場合 → Analyticsを優先
-
開発フェーズ:
- 開発初期/ベータ版 → Crashlyticsを優先して安定性を確保
- 安定稼働後の改善フェーズ → Analyticsを追加して利用状況を把握
-
リソース制約:
- 時間やリソースが限られている場合は、まずCrashlyticsを実装し、その後Analyticsを追加するアプローチが一般的
アプリの規模が小さく、Firebase FirestoreとAuthのみを利用している状況であれば、まずはCrashlyticsを実装して安定稼働を確保し、その後Analyticsを追加して利用状況の把握に進むという段階的なアプローチが合理的。
Discussion