当应用程序在调试中运行时,如何禁用Firebase崩溃报告?


75

我已经成功实现了Firebase Crash Reporting,但是我需要在应用运行时禁用该服务,并撤消“调试” Build Variant,以避免开发过程中控制台发生非真实的崩溃。

官方文档对此没有任何说明。


if (!development) { FirebaseCrash.report(e);}
土蚣

1
谢谢@James_Parsons,但我不是那个意思。我需要禁用自动崩溃报告,而不仅仅是禁用对API的手动调用。
facundomr

releaseCompile 'com.google.firebase:firebase-crash:9.8.0' 这行不行吗?应该只为您的发行版本添加依赖项,因此在开发库时不会将其添加到项目中,对吗?
Ankit Mundada'1

Answers:


48

更新:使用Google Play服务/ Firebase 11+,您现在可以在运行时禁用崩溃报告。FirebaseCrash.setCrashCollectionEnabled()(感谢@Tyler Carberry

旧答案:

只要社区能够推测,就没有官方的支持。我建议执行此操作的最佳方法是,在仪表板中设置多个Firebase应用程序,每种构建类型一个,并根据构建版本设置多个指向每个不同应用程序的google_services.json文件。


22
嗨,我是Crash Reporting团队的成员。我们正在研究为您提供一种以编程方式禁用崩溃报告的方法。我们还发现,出于法律原因,世界上某些地区的某些开发人员不允许收集崩溃,并且他们还需要一种在运行时禁用崩溃报告的方法。
道格·史蒂文森

8
@DougStevenson自您发表评论以来已经有一段时间了,我似乎没有找到任何禁用自动崩溃报告的方法。目前有什么办法吗?
阿林

5
有关此答案的更多详细信息,请参阅:firebase.googleblog.com/2016/08/…–
弗兰克(Frank)

3
@ColinWhite很抱歉,目前没有可用。如果您在Twitter(或我的CodingDoug)上关注Firebase,您可能会以这种方式听到任何新内容。
道格·史蒂文森

6
使用Google Play服务11.0,您现在可以在运行时禁用崩溃报告。FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);
泰勒·卡伯里


25

最近引入了以官方方式禁用Firebase崩溃报告的可能性。您需要将Firebase Android SDK升级到至少11.0.0版本

为此,您需要编辑AndroidManifest.xml并添加:

<meta-data
   android:name="firebase_crashlytics_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"/>
...

该标志firebase_crash_collection_enabled适用于Firebase 9.2.1版吗?
rraallvv

@rraallvv不,该功能尚不可用
evi

这是一个很好的解决方案,它基于已记录的禁用Crashlytics的机制。清单清单现在是'firebase_crashlytics_collection_enabled'。
里昂,

@Leon,对不起队友,你错了。这种方法实际上是用于在清单中启用/禁用事物的android标准,这一事实类似于Crashlytics文档所使用的方法是完全随机的!
evi

不是“ firebase_crash_collection_enabled”,而是“ firebase_crashlytics_collection_enabled”-来自firebase.google.com/docs/crashlytics/customize-crash-reports
Alex Shevelev

11

在我的应用程序类中,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
        }
    });
}

它之所以有效,是因为它需要oldHandler,其中包括Firebase 1

 final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();

走出处理路径


11

您可以将firebase崩溃依赖项更改为仅发行依赖项。

为此,您将其定义为releaseCompile依赖项

releaseCompile 'com.google.firebase:firebase-crash:9.4.0'

现在,它将仅包含在发行版本中。如果您想要崩溃报告的其他自定义构建类型,则可以将其添加到其中。

customBuildTypeCompile 'com.google.firebase:firebase-crash:9.4.0'

6
仅供参考,即使使用此方法,Firebase似乎也会将所有崩溃保存在数据库中,并且,如果您在模拟器上安装了发行版(例如,要测试ProGuard),则它将上载所有已保存的崩溃。
乔尔(Joel)

9

我使用的简单技巧是仅在发布版本中添加firebase崩溃报告依赖项 build.gradle文件。

这将从调试版本类型中删除崩溃报告库,并将其仅添加到发行版本中。

dependencies {
    releaseCompile 'com.google.firebase:firebase-crash:10.2.0'
}

7

受到这个相关答案的启发和此处其他,我想出了这个方便的解决方案。

使用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 / [package] /ForestFire.java

import timber.log.Timber;

public class ForestFire extends Timber.DebugTree {}

src / release / java / [package] /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());

6

首先在gradle文件中初始化变量,然后检查它是处于调试模式还是处于释放模式。提交崩溃报告的最佳方法是在Application类中。

Build.gradle

    buildTypes {
         release {
             buildConfigField "Boolean", "REPORT_CRASH", '"true"'
             debuggable false
         }
         debug {
             buildConfigField "Boolean", "REPORT_CRASH", '"false"'
             debuggable true
         }
    }

现在首先检查模式,如果崩溃则提交崩溃报告。

应用程序

    /** 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);
            }
        }
    });

9
对于第一部分,您可以简单地使用BuildConfig.DEBUG
Bronx

4

尽管您可以停用Firebase分析,但当前您无法禁用Firebase崩溃报告。

因此,一种方法是在同一个Firebase项目中创建另一个具有不同ID的应用。之后,您只需要更改appID即可启用或禁用Firebase崩溃报告。为了方便起见,我在下面创建了两个应用程序:

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

编辑2:

基本上,在上述解决方案中,您将在Firebase项目中制作两个不同的应用程序,并且通过这种方式,您可以区分开发和生产错误。

不建议使用FYI Firebase崩溃报告。您应该使用Fabrics Crashlytics(由Google拥有)。它具有一些非常酷的功能。


2

对于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);
}

资源


1

首先,您将必须创建debugrelease构建变体,然后使用布尔值设置变量。然后,您需要从扩展的Java文件中获取该值,application即从启用位置开始Fabric崩溃报告的位置开始。

下面给出一个代码示例。

在您的应用程序的build.gradle文件,添加以下行来创建2个构建变量debugrelease,然后添加一个变量与布尔值。

defaultConfig {
    buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'true'
}

buildTypes {
    debug {
        applicationIdSuffix ".debug"
        versionNameSuffix 'DEBUG'
        buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'false'
    }
    release {
        minifyEnabled false
    }
}

然后,当您尝试添加Fabric崩溃报告时,请检查以下值:ENABLE_ANALYTICS

公共类测试扩展了应用{

private GoogleAnalytics googleAnalytics;
private static Tracker tracker;

@Override
public void onCreate() {
    super.onCreate();
    if (BuildConfig.ENABLE_ANALYTICS)
        Fabric.with(this, new Crashlytics());
    }
}

您可以ENABLE_ANALYTICS通过ctrl+单击值来查看的值。希望这可以帮助。


1

当用户以Debug模式或Release模式运行应用程序时,最简单的解决方案是:

AndroidManifest.xml:

<meta-data
            android:name="firebase_crash_collection_enabled"
            android:value="${analytics_deactivated}"/>

build.gradle(模块:应用)

buildTypes {

        debug {
            manifestPlaceholders = [analytics_deactivated: "false"]
        }

        release {
            manifestPlaceholders = [analytics_deactivated: "true"]

        }
    }

因此,当应用程序处于发布模式时,crashlatics将被打开,而应用程序将在调试模式下运行,它将被关闭。


0

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控制台中区分崩溃报告。


0

如前所述-没有官方的方法可以做到这一点。但是如@ mark-d所述,对我来说最糟糕的解决方法是重置DefaultUncaughtExceptionHandlerhttps://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;
}

0
public class MyApp extends Application {
    public static boolean isDebuggable;

    public void onCreate() {
        super.onCreate();
        isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
        FirebaseCrash.setCrashCollectionEnabled(!isDebuggable);
    }
}

0

我猜想最近的Firebase crashlytics具有此实现。

 FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.