はじめに
※この記事は、以下の記事の続編です。
【Mac不要】FlutterアプリにFirebase SDKを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編
この記事ではその後、FlutterアプリにFirebase Crashlyticsを組み込み、iOS, Androidの両端末のクラッシュ情報をFirebaseコンソールに連携できるようになるまでの手順を説明します。
では早速始めてみましょう。
謝辞
Firebase Crashlytics - Android
Android向けの作業を進めるにあたっては、以下の記事がとても助けになりました。ありがとうございます。
- Firebase Crashlyticsを導入する - @tnagao3000
- Serverless連載4: Firebase CrashlyticsでAndroidアプリのエラーログをさくっと収集する - フューチャー開発者ブログ
Firebase Crashlytics - iOS
iOS向けの作業を進めるにあたっては、以下の記事がとても助けになりました。
ありがとうございます。
前提
この記事は、以下に当てはまる人向けの iOS/Android 対応アプリにFirebase Crashlyticsを組み込む手順を紹介します。
- 開発機はWindowsだ
- Macを持っていない
- Flutterで開発したい
- Apple Developer Programに既に登録している。
開発環境の前提
以下の2本の記事の手順に沿ってFlutterアプリをCodemagicでビルドし、さらに自身のiOS端末/Android端末のアプリの利用状況(Analytics)がFirebaseに連携されている状態にしておいてください。
- 【Mac不要】開発中のFlutter製アプリをiOSとAndroidに実機配備する手順 - Codemagic編
- 【Mac不要】FlutterアプリにFirebase SDKを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編
ソースコードの公開
この記事の手順で作成したソースコードはGithubで公開しています。併せてご参照ください。
https://github.com/atsuteru/flutter_firebase_0507/tree/Qiita-FirebaseCrashlytics-v1.0
本文
FlutterアプリにFirebase Crashlyticsを組み込む
FlutterにFirebase Crashlyticsを組み込むために、まずはライブラリのページを確認するようにしましょう。Google検索のキーワードはFlutter Firebase Crashlytics
で大丈夫。以下のページが見つかればOKです。
firebase_crashlytics | Flutter Package - Dart Pub
なぜページを確認するかというと、次の2点です。
- 最新バージョンのバージョン番号を調べる。
- 最新バージョンの導入方法を学ぶ。
バージョン番号は、タイトルに記載されています。
2020/5/11時点のタイトルは次のようになっていました。
firebase_crashlytics 0.1.3+3
つまり最新バージョンは 0.1.3+3
だということ。※最後の+3
までがバージョン番号です。
またそのページの説明の中に、以下の見出しがありますので、それを読み解いて作業を進めることになります。
- Usage ・・・ ライブラリの使い方
- Import the firebase_crashlytics plugin ・・・ Flutterアプリへの組み込み手順
- Android integration ・・・ Androidで動作させるための追加の手順
- iOS Integration ・・・ iOSで動作させるための追加の手順
- Use the plugin ・・・ ライブラリを利用する実装方法
ではこれでもうできましたね!お疲れ様ですっ。
・・・
となればいいのですが、何かと上手くいかなかったりします。それだけ進化のスピードが速いということですね!(ポジティブ
というわけで、以下、私がいろいろ試した中で、うまくいった最短の手順を紹介します。
FlutterアプリにFirebase Crashlyticsを組み込む
この手順はライブラリのinstallingの手順に沿ってます。
Flutterにライブラリを組み込むには、pubspec.yaml
を編集します。dependencies
に最新のバージョンfirebase_crashlytics: ^0.1.3+
を追記しましょう。追記する箇所はflutter
,firebase_core
よりも後にしないと、私はうまくいきませんでした。
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.4+3
firebase_crashlytics: ^0.1.3+3
Flutterアプリに、FirebaseコンソールのCrashlyticsと連携するためのコードを追加する
この手順はライブラリのUse the pluginの手順に沿っています。
Flutterアプリが実行中にクラッシュしたことを検出し、FirebaseコンソールのCrashlyticsに連携できるようにするために、以下のコードを追加します。
あと、「▼▼▼」「▲▲▲」などが付いたコメントは、この記事での説明用ですので、あなたのコードには書かないでください。念のため(^^;
2020/06/04 修正
runZonedのonError引数がdeprecatedとしてマークされていたため、ソースコードを更新しました。参考: Migrate runZoned calls to runZonedGuarded
//▼▼▼ 以下、修正前のコード ▼▼▼
//import 'package:flutter/material.dart';
//void main() => runApp(MyApp());
//▼▼▼ 以下、修正後のコード ▼▼▼
import 'dart:async';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
void main() {
Crashlytics.instance.enableInDevMode = true;
FlutterError.onError = Crashlytics.instance.recordFlutterError;
runZonedGuarded(() async {
runApp(MyApp());
}, (e, s) async => await Crashlytics.instance.recordError(e, s));
}
上記の各コードの説明は、ライブラリのページに書いてありますので、割愛します。
Flutterアプリに、Crashlyticsとの連携を試すためのテストコードを追加する
この手順は任意ですが、もしここまでを私の記事に沿って作ってこられた場合は、ぜひやってみてください。
この手順は、ライブラリのExampleで公開されているサンプルコードを取り入れるものです。
以下の「追加ココカラ」「追加ココマデ」の間の部分を、実装しましょう。この実装はFirebase Crashlyticsライブラリのいろんな機能を実験できるボタンを画面に表示します。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
//▼▼▼ 追加ココカラ ▼▼▼
Text(
'Firebase Crashlytics Tests:',
),
FlatButton(
child: const Text('Key'),
onPressed: () {
Crashlytics.instance.setString('foo', 'bar');
}),
FlatButton(
child: const Text('Log'),
onPressed: () {
Crashlytics.instance.log('baz');
}),
FlatButton(
child: const Text('Crash'),
onPressed: () {
// Use Crashlytics to throw an error. Use this for
// confirmation that errors are being correctly reported.
Crashlytics.instance.crash();
}),
FlatButton(
child: const Text('Throw Error'),
onPressed: () {
// Example of thrown error, it will be caught and sent to
// Crashlytics.
throw StateError('Uncaught error thrown by app.');
}),
FlatButton(
child: const Text('Async out of bounds'),
onPressed: () {
// Example of an exception that does not get caught
// by `FlutterError.onError` but is caught by the `onError` handler of
// `runZoned`.
Future<void>.delayed(const Duration(seconds: 2), () {
final List<int> list = <int>[];
print(list[100]);
});
}),
FlatButton(
child: const Text('Record Error'),
onPressed: () {
try {
throw 'error_example';
} catch (e, s) {
// "context" will append the word "thrown" in the
// Crashlytics console.
Crashlytics.instance
.recordError(e, s, context: 'as an example');
}
}),
//▲▲▲ 追加ココマデ ▲▲▲
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Android向けの追加の導入手順を実施する
Android向けには、以下の手順が必要です。
この手順はライブラリのAndroid integrationの手順に沿っています。
1) Android向けのライブラリの組み込みを定義する
以下の「追加ココカラ」「追加ココマデ」の間の部分を、追加しましょう。
buildscript {
repositories {
google()
jcenter()
//▼▼▼ 追加ココカラ ▼▼▼
maven {
url 'https://maven.fabric.io/public'
}
//▲▲▲ 追加ココマデ ▲▲▲
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.google.gms:google-services:4.3.3'
//▼▼▼ 追加ココカラ ▼▼▼
classpath 'io.fabric.tools:gradle:1.26.1'
//▲▲▲ 追加ココマデ ▲▲▲
}
}
allprojects {
repositories {
google()
jcenter()
//▼▼▼ 追加ココカラ ▼▼▼
maven {
url 'https://maven.fabric.io/public'
}
//▲▲▲ 追加ココマデ ▲▲▲
}
}
2) Android向けのプラグインの読み込みを定義する
apply plugin
の箇所は、com.google.gms.google-services
よりも前であることに注意してください。
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
//▼▼▼ 追加ココカラ ▼▼▼
apply plugin: 'io.fabric'
//▲▲▲ 追加ココマデ ▲▲▲
apply plugin: 'com.google.gms.google-services'
//▲▼▲(中略)▲▼▲
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.google.firebase:firebase-analytics:17.2.2'
//▼▼▼ 追加ココカラ ▼▼▼
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
//▲▲▲ 追加ココマデ ▲▲▲
ちなみに、fabric
は、Firebase Crashlyticsの旧サービスです。現在はFirebase Crashlytics
に移行が進められていますが、内部的にはまだfabric
のライブラリを利用しているということですね。
iOS向けの追加の導入手順を実施する
次はiOS向けの導入手順ですが・・・
結論から言うと、iOS向けには追加のライブラリの導入手順は不要です。
なぜならば、FlutterにFirebase関連のパッケージを組み込んだ状態でのiOS向けビルドは、その組み込み情報をもとにPodfileを自動生成し、iOS向けのライブラリの組み込みまでを自動的にやってくれるから、です。
なのでこれは蛇足ですが、iOS
ディレクトリ直下にPodfileをコミットしようものなら、上記の自動生成がスキップされてしまい、ビルドが通らなくなりますのでご注意を。
なお・・・Podfile
とは、iOSアプリのライブラリを管理できるCocoaPodsというツールの設定ファイルで、ios/Runner.xcodeproj/project.pbxproj
の書き換えをやってくれるものです。WindowsでCocoaPodsを動作させるのはいばらの道ですので、Macを持たない我々は、FirebaseがCodemagic上でそれを自動的にやってくれるという恩恵にあずかりましょう。。。
iOS向けに不要になったコードを削除する
とは言いつつ1つだけ、iOS向けにやっておかないといけない手順があります。
以下のように、コードを2行削除してください。(「この行を消す!」の2行)
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
//@import Firebase; ←この行を消す!
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// [FIRApp configure]; ←この行を消す!
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
私の記事の手順に沿ってやってこられた方はお気づきだと思いますが、これは「Firebase SDK」の組み込みの手順として追加した2行です。
今回、Firebase CrashlyticsをFlutterに組み込んだことによって、不要となったようです。(私はこれを削除しないとうまくいかなかった)
FilebaseコンソールでCrashlyticsと連携できたことを確認する
連携前にFilebaseコンソールでアプリのCrashlyticsページを覗いてみると、次の画面が表示されました。
SDKの組み込みは先程までの手順で終えているので、ソースコードをpushし、Codemagicによるリリースビルドの結果を待ちましょう。
Androidでの確認
Codemagicから届いたビルド成功の通知メールから、再インストールしました。
そしてFirebaseコンソールに戻ると・・・「インストールが完了しました」の表示が!ちゃんと連携できましたね。
クラッシュはまだありませんね。
ここで一つ注意です!
このページはデフォルトで、アプリが異常終了したレベルのクラッシュだけを表示するようにフィルタされています。青いラベル「イベントの種類"クラッシュ"」の「×」を押して、フィルタを解除しておきましょう。
では、実際に"クラッシュ!"・・・はできませんが、仕込んでおいたボタンでアプリでエラーを起こしてみましょう。
アプリは一度終了し、起動しなおしてください。(初回起動のみ、うまく連携されないようです)
そしてアプリの画面の「Key」「Log」「Crash」「Throw Error」「Async out of bounds」「Record Error」をガンガンタップしてみましょう。
すると数分もたたないうちに・・・Crashlyticsページに連携されましたね!
iOSでの確認
Codemagicから届いたビルド成功の通知メールから、再インストールしましょう。
※iOSアプリは、TestFlightの手順(記事:【Mac不要】開発中のFlutter製アプリを仲間のiOS端末に実機配備する手順 - Codemagic&TestFlight編)をすでに実施している場合は、TestFlightから「Update」することでこのバージョンをインストールしましょう。それ以外はの方はCodemagicから届くメールからインストールしてください。
iOSアプリでも同じように、アプリの画面の「Key」「Log」「Crash」「Throw Error」「Async out of bounds」「Record Error」をガンガンタップしてみましょう。
私の場合は少し時間がかかりましたが・・・Crashlyticsページに連携されましたね!
おわりに
これで、本記事の目的は達成できました。しかし、これでやっと開発のスタートラインに立ったにすぎません。
この記事の続編として、あと1本を予定しているので、乞うご期待!
- Google Photo APIと連携し、利用者のフォトアルバムにアクセスする
最後に、この記事がFlutterを始められる方にとって少しでも助けになれば、幸いです。