【问题标题】:How to disable Firebase Crash Reporting when the app is running on debug?应用程序在调试时运行时如何禁用 Firebase 崩溃报告?
【发布时间】: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' 这不行吗?它应该只为您的发布版本添加依赖项,因此在开发库时不会将其添加到项目中,对吧?

标签: android firebase firebase-crash-reporting


【解决方案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://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;
                      }
                      

                      【讨论】:

                        【解决方案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);
                            }
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2011-01-18
                          • 2014-04-08
                          • 2015-03-31
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-11-15
                          相关资源
                          最近更新 更多