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

Posted

技术标签:

【中文标题】应用程序在调试时运行时如何禁用 Firebase 崩溃报告?【英文标题】:How to disable Firebase Crash Reporting when the app is running on debug? 【发布时间】:2016-09-20 16:17:00 【问题描述】:

我已成功实现 Firebase Crash Reporting,但我需要在应用运行时禁用该服务,撤消“调试”构建变体,以避免在开发过程中控制台出现非实际崩溃。

官方文档没有说明这一点。

【问题讨论】:

if (!development) FirebaseCrash.report(e); 谢谢@James_Parsons,但我不是那个意思。我需要禁用自动崩溃报告,而不仅仅是手动调用 API。 releaseCompile 'com.google.firebase:firebase-crash:9.8.0' 这不行吗?它应该只为您的发布版本添加依赖项,因此在开发库时不会将其添加到项目中,对吧? 查看这个答案:***.com/a/48384549/3166417 【参考方案1】:

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

旧答案:

据社区推测,对此没有官方支持。我建议执行此操作的最佳方法是,在您的仪表板中设置多个 Firebase 应用,每个构建类型一个,并根据构建变体设置多个指向每个不同应用的 google_services.json 文件。

【讨论】:

您好,我在崩溃报告团队工作。我们正在研究为您提供一种以编程方式禁用崩溃报告的方法。我们还发现,世界上某些地区的一些开发人员出于法律原因不允许收集崩溃,他们还需要一种方法来在运行时禁用崩溃报告。 @DougStevenson 自从您发表评论以来已经有一段时间了,我似乎没有找到任何禁用自动崩溃报告的方法。目前有什么办法吗? 有关此答案的更多详细信息,请参阅:firebase.googleblog.com/2016/08/… @ColinWhite 抱歉,目前还没有可用的东西。如果你在 Twitter 上关注 Firebase(或者我是 CodingDoug),你很可能会通过这种方式听说任何新事物。 借助 Google Play 服务 11.0,您现在可以在运行时禁用崩溃报告。 FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);【参考方案2】:

使用 Google Play 服务 11.0,您现在可以在运行时禁用崩溃报告。

FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);

【讨论】:

【参考方案3】:

Recently 引入了以官方方式禁用 Firebase 崩溃报告的可能性。您需要将 firebase android sdk 至少升级到 11.0.0 版

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

<meta-data
   android:name="firebase_crashlytics_collection_enabled"
   android:value="false" />

&lt;application&gt; 块内。

您可以使用 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 不,该功能尚不可用 这是一个很好的解决方案,它基于禁用 Crashlytics 的记录机制。顺便说一下,清单键现在是“firebase_crashlytics_collection_enabled”。 @Leon,对不起,伙计,你错了。这种方法是在清单中启用/禁用事物的事实上的 android 标准,与 Crashlytics 文档使用的方法相似的事实是完全随机的! 不是“firebase_crash_collection_enabled”而是“firebase_crashlytics_collection_enabled”——来自firebase.google.com/docs/crashlytics/customize-crash-reports【参考方案4】:

在我的应用程序类中,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 一个

 final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();

处理路径之外

【讨论】:

【参考方案5】:

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

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

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

现在它只会包含在发布版本中。如果您有其他需要崩溃报告的自定义构建类型,可以将其添加到其中。

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

【讨论】:

仅供参考,即使使用这种方法,Firebase 似乎也会将所有崩溃都保存在数据库中,如果您在模拟器上安装了发布版本(例如,为了测试 ProGuard),它将然后上传所有保存的崩溃。【参考方案6】:

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

这将从调试构建类型中删除崩溃报告库,并仅在发布构建中添加它。

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

【讨论】:

【参考方案7】:

受this related answer 和其他人的启发,我想出了这个方便的解决方案。

使用 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());

【讨论】:

【参考方案8】:

首先初始化gradle文件中的变量,查看是debug还是release模式。提交崩溃报告的最佳方式是在 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);
            
        
    );

【讨论】:

对于第一部分,您可以简单地使用 BuildConfig.DEBUG【参考方案9】:

虽然您可以停用 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 项目中制作了两个不同的应用程序,这样您就可以将开发和生产错误分开。

仅供参考,Firebase 崩溃报告已弃用。您应该使用Fabrics Crashlytics(归谷歌所有)。它有一些非常酷的功能。

【讨论】:

【参考方案10】:

对于FirebaseAnalytics 类。 禁用收藏:setAnalyticsCollectionEnabled(false); 启用收藏:setAnalyticsCollectionEnabled(true); 或在应用程序标签中写信给AndroidManifest.xml&lt;meta-data android:name="firebase_analytics_collection_enabled" android:value="false" /&gt;

可能的用途:

if (BuildConfig.DEBUG) //disable for debug
    mFirebaseAnalytics.setAnalyticsCollectionEnabled(false);

Source

【讨论】:

【参考方案11】:

首先,您必须创建 debugrelease 构建变体,然后设置具有布尔值的变量。然后,您需要从扩展 application 的 java 文件中获取该值,即从您启用 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());
    

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

【讨论】:

【参考方案12】:

用户在Debug模式或Release模式下运行应用时最简单的解决方案:

AndroidManifest.xml:

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

build.gradle(模块:app)

buildTypes 

        debug 
            manifestPlaceholders = [analytics_deactivated: "false"]
        

        release 
            manifestPlaceholders = [analytics_deactivated: "true"]

        
    

因此,当应用处于 release 模式时,crashlatics 将被打开并且应用在 debug 模式下运行时,它会被关闭。

【讨论】:

【参考方案13】:

我猜最近的 firebase crashlytics 有这个实现。

 FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)

【讨论】:

【参考方案14】:

我使用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 控制台中轻松区分崩溃报告。

【讨论】:

【参考方案15】:

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

【讨论】:

【参考方案16】:
public class MyApp extends Application 
    public static boolean isDebuggable;

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

【讨论】:

以上是关于应用程序在调试时运行时如何禁用 Firebase 崩溃报告?的主要内容,如果未能解决你的问题,请参考以下文章

在 Unity Firebase SDK 中禁用广告 ID (AAID) 收集运行时

如何在 iOS 中禁用 Firebase/Core 调试消息

DirectX 11:运行简单的 DirectX 应用程序时运行时崩溃

为啥 Kubernetes 的容器在 runsc (gVisor) 上作为 Docker 中的运行时运行时会失败?

为 iOS 调试版本禁用 Firebase Analytics

添加新对象时运行时覆盖列表元素[重复]