Firebase Crash Reportingを正常に実装しましたが、アプリの実行中に「debug」ビルドバリアントを元に戻すときにサービスを無効にして、開発中のコンソールでの実際のクラッシュを回避する必要があります。
公式文書ではこれについて何も述べられていません。
更新:Google Play Services/Firebase 11以降では、実行時にクラッシュレポートを無効にできるようになりました。 FirebaseCrash.setCrashCollectionEnabled()
(ありがとう @ Tyler Carberry )
古い回答:
コミュニティが推測できる限り、これに対する公式のサポートはありません。これを行うための最良の方法は、ビルドタイプごとに1つずつ、ダッシュボードに複数のFirebaseアプリをセットアップし、ビルドバリアントに応じて各アプリにリダイレクトする複数のgoogle_services.jsonファイルをセットアップすることです。
Google Play Services 11.0では、実行時のクラッシュレポートを無効にできるようになりました。
FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);
最近 Firebaseクラッシュレポートを公式な方法で無効にする可能性が導入されました。 firebase Android sdkを少なくともバージョン11.0.0にアップグレードする必要があります
そのためには、AndroidManifest.xml
を編集して追加する必要があります:
<meta-data
Android:name="firebase_crash_collection_enabled"
Android:value="false" />
<application>
ブロック内。
FirebaseCrash.isCrashCollectionEnabled() を使用して、実行時にFirebaseクラッシュレポートが有効になっているかどうかを確認できます。
以下は、デバッグビルドでFirebaseクラッシュレポートを無効にする完全な例です。
build.gradle:
...
buildTypes {
release {
...
resValue("bool", "FIREBASE_CRASH_ENABLED", "true")
}
debug {
...
resValue("bool", "FIREBASE_CRASH_ENABLED", "false")
}
}
...
dependencies {
...
compile "com.google.firebase:firebase-core:11.0.0"
compile "com.google.firebase:firebase-crash:11.0.0"
...
}
AndroidManifest.xml:
<application>
<meta-data
Android:name="firebase_crash_collection_enabled"
Android:value="@bool/FIREBASE_CRASH_ENABLED"/>
...
私のアプリケーションクラス、onCreate()
if (BuildConfig.DEBUG) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
Log.wtf("Alert", paramThrowable.getMessage(), paramThrowable);
System.exit(2); //Prevents the service/app from freezing
}
});
}
Firebaseを含むoldHandlerを使用するため機能します
final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();
処理経路外
Firebase crash依存関係をリリースのみの依存関係に変更できます。
これを行うには、releaseCompile依存関係として定義します
releaseCompile 'com.google.firebase:firebase-crash:9.4.0'
これで、リリースビルドにのみ含まれるようになります。クラッシュレポートを作成したい他のカスタムビルドタイプがある場合は、それに追加できます。
customBuildTypeCompile 'com.google.firebase:firebase-crash:9.4.0'
私が使用したシンプルで簡単なトリックは、build.gradle
ファイルのみのリリースビルドでfirebaseクラッシュレポートの依存関係を追加することです。
これにより、デバッグビルドタイプからクラッシュレポートライブラリが削除され、リリースビルドのみに追加されます。
dependencies {
releaseCompile 'com.google.firebase:firebase-crash:10.2.0'
}
この関連する答え とここにある他のものに触発され、私はこの便利なソリューションを思いつきました。
ロギングに Timber を使用して、デバッグビルドとリリースビルド用にTreeサブクラスの異なる実装を作成しました。デバッグでは、logcatに書き込むDebugTreeに従います。リリースでは、例外と優先度の高いログをFirebaseに転送し、残りは削除します。
build.gradle
dependencies {
...
compile 'com.jakewharton.timber:timber:4.3.0'
releaseCompile 'com.google.firebase:firebase-crash:9.0.2'
}
src/debug/Java/[パッケージ] /ForestFire.Java
import timber.log.Timber;
public class ForestFire extends Timber.DebugTree {}
src/release/Java/[パッケージ] /ForestFire.Java
import Android.util.Log;
import com.google.firebase.crash.FirebaseCrash;
import timber.log.Timber;
public class ForestFire extends Timber.Tree {
@Override
protected void log(int priority, String tag, String message, Throwable t) {
if (Log.WARN <= priority) {
FirebaseCrash.log(message);
if (t != null) {
FirebaseCrash.report(t);
}
}
}
}
アプリの起動
Timber.plant(new ForestFire());
まず、gradleファイルの変数を初期化し、デバッグモードかリリースモードかを確認します。クラッシュレポートを送信する最適な方法は、Applicationクラス内です。
Build.gradle
buildTypes {
release {
buildConfigField "Boolean", "REPORT_CRASH", '"true"'
debuggable false
}
debug {
buildConfigField "Boolean", "REPORT_CRASH", '"false"'
debuggable true
}
}
まず、モードを確認し、クラッシュした場合はクラッシュレポートを送信します。
Application.Java
/** Report FirebaseCrash Exception if application crashed*/
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
/** Check whether it is development or release mode*/
if(BuildConfig.REPORT_CRASH)
{
FirebaseCrash.report( e);
}
}
});
現在、Firebase Analyticsを無効にすることはできますが、Firebaseクラッシュレポートを無効にすることはできません。
そのため、これを行う1つの方法は、同じfirebaseプロジェクト内で異なるIDを持つ別のアプリを作成することです。その後、appIDを変更して、Firebaseクラッシュレポートを有効または無効にする必要があります。便宜上、以下の2つのアプリを作成しました。
AppID:com.Android-リリースビルドタイプ用
AppID:com.Android.debug-デバッグビルドタイプ用
詳細については、以下のリンクに従ってください:
https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-Android-app-builds.html
編集:AndroidプロジェクトのappIDを何度も変更する必要はありません。デバッグビルドタイプに別のappIDを使用するより良い方法があります。
Android {
defaultConfig {
applicationId "com.Android"
...
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
}
詳細については、リンクをご覧ください。
https://developer.Android.com/studio/build/application-id.html
Edit2:
基本的に上記のソリューションでは、Firebaseプロジェクトで2つの異なるアプリを作成しています。この方法で、開発エラーと本番エラーを分離できます。
FYI Firebaseクラッシュレポートは廃止されました。 Fabrics Crashlytics (Google所有)を使用する必要があります。いくつかの本当にクールな機能があります。
FirebaseAnalytics
クラスの場合。
コレクションを無効にします:setAnalyticsCollectionEnabled(false);
コレクションを有効にする:setAnalyticsCollectionEnabled(true);
またはアプリケーションタグのAndroidManifest.xml
に書き込みます:<meta-data Android:name="firebase_analytics_collection_enabled" Android:value="false" />
可能な用途:
if (BuildConfig.DEBUG){ //disable for debug
mFirebaseAnalytics.setAnalyticsCollectionEnabled(false);
}
最初に、debug
およびrelease
ビルドバリアントを作成してから、ブール値で変数を設定する必要があります。次に、Javaファイルからapplication
を拡張する値、つまりFabric
クラッシュレポートを有効にする場所からその値を取得する必要があります。
コード例を以下に示します。
アプリのbuild.gradle
ファイルに次の行を追加して、2つのビルドバリアントdebug
およびrelease
を作成し、ブール値の変数を追加します。
defaultConfig {
buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'true'
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix 'DEBUG'
buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'false'
}
release {
minifyEnabled false
}
}
次に、Fabric
クラッシュレポートを追加しようとしているときに、ENABLE_ANALYTICS
の値を確認します
パブリッククラスTestはApplication {を拡張します
private GoogleAnalytics googleAnalytics;
private static Tracker tracker;
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.ENABLE_ANALYTICS)
Fabric.with(this, new Crashlytics());
}
}
ctrl
でENABLE_ANALYTICS
の値を確認し、値をクリックします。お役に立てれば。
ローカル/プロダクションビルドのフィルターとしてversionCode
を使用します。
gradle.properties
VERSION_CODE=1
app/build.gradle
Android {
defaultConfig {
versionCode VERSION_CODE as int
}
}
アプリの新しいバージョンを公開するときは、コマンドラインから新しい値を設定するだけです。
./gradlew build -PVERSION_CODE=new_value
それ以外の場合、Android Studioからビルドするときは常に同じversionCode
を取得するため、Firebaseコンソールでクラッシュレポートを簡単に区別できます。
前に述べたように、これを行う公式の方法はありません。しかし、@ mark-dで述べたように、私にとって最悪の回避策はDefaultUncaughtExceptionHandler
( https://stackoverflow.com/a/39322734/4245651 )をリセットすることです。
ただし、提案されたSystem.exit(2)
を呼び出すだけの場合、例外が発生すると、ダイアログメッセージが表示されず、デバッグログを取得することなく、アプリが即座に閉じられます。これが重要な場合は、デフォルトのハンドラーを復元する方法があります。
if (BuildConfig.DEBUG) {
final Thread.UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler();
if (currentHandler.getClass().getPackage().getName()
.startsWith("com.google.firebase")) {
final Thread.UncaughtExceptionHandler defaultHandler =
getPrivateFieldByType(currentHandler, Thread.UncaughtExceptionHandler.class);
Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
}
}
どこ
public static <T> T getPrivateFieldByType(Object obj, Class<T> fieldType) {
if (obj != null && fieldType != null) {
for (Field field : obj.getClass().getDeclaredFields()) {
if (field.getType().isAssignableFrom(fieldType)) {
boolean accessible = field.isAccessible();
if (!accessible) field.setAccessible(true);
T value = null;
try {
//noinspection unchecked
value = (T) field.get(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!accessible) field.setAccessible(false);
return value;
}
}
}
return null;
}
public class MyApp extends Application {
public static boolean isDebuggable;
public void onCreate() {
super.onCreate();
isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
FirebaseCrash.setCrashCollectionEnabled(!isDebuggable);
}
}