如何在应用处于 运行 调试时禁用 Firebase 崩溃报告?
How to disable Firebase Crash Reporting when the app is running on debug?
我已经成功实现了 Firebase 崩溃报告,但是我需要在应用程序 运行 撤消 'debug' Build Variant 时禁用该服务,以避免控制台中的非真实崩溃开发中。
官方文档对此没有任何说明。
更新:
使用 Google Play Services / Firebase 11+,您现在可以在运行时禁用崩溃报告。 FirebaseCrash.setCrashCollectionEnabled()
(感谢@Tyler Carberry)
旧答案:
据社区推测,没有官方支持。我建议这样做的最佳方法是,在您的仪表板中设置多个 Firebase 应用程序,每个构建类型一个,并根据构建变体设置多个 google_services.json 文件指向每个不同的应用程序。
首先初始化gradle文件中的变量,检查是debug还是release模式。提交崩溃报告的最佳方式是在应用程序中 class.
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);
}
}
});
在我的应用程序 class 中,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 的处理程序
final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();
超出处理路径
受到 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/[包]/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());
我使用 versionCode
作为 local/production 构建的过滤器。
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 控制台中的崩溃报告。
您可以将 firebase 崩溃依赖项更改为仅发布依赖项。
为此,您将其定义为 releaseCompile 依赖项
releaseCompile 'com.google.firebase:firebase-crash:9.4.0'
现在它只会包含在发布版本中。如果您有其他需要崩溃报告的自定义构建类型,您可以将其添加到它们中。
customBuildTypeCompile 'com.google.firebase:firebase-crash:9.4.0'
目前您无法禁用 firebase 崩溃报告,但您可以停用 firebase 分析。
因此,一种方法是在同一 firebase 项目中创建另一个具有不同 ID 的应用程序。在此之后,您只需更改 appID 即可启用或禁用 firebase 崩溃报告。为了方便起见,我在下面创建了两个应用程序:
AppID:com.android - 对于发布构建类型
AppID:com.android.debug - 用于调试构建类型
更多详情请关注下方link:
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"
}
}
}
查看 link 了解更多详情:
https://developer.android.com/studio/build/application-id.html
编辑2:
基本上在上面的解决方案中,您在 Firebase 项目中制作了两个不同的应用程序,这样您就可以将开发和生产错误分开。
仅供参考 Firebase 崩溃报告已弃用。您应该使用 Fabrics Crashlytics(归 Google 所有)。它有一些非常酷的功能。
如前所述 - 没有官方方法可以做到这一点。但是@mark-d 提到的对我来说最糟糕的解决方法是重置 DefaultUncaughtExceptionHandler
()。
但如果您只是按照建议调用 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;
}
我使用的简单易行的技巧是仅在 build.gradle
文件中的发布版本中添加 firebase 崩溃报告依赖项。
这将从调试构建类型中删除崩溃报告库,并仅将其添加到发布构建中。
dependencies {
releaseCompile 'com.google.firebase:firebase-crash:10.2.0'
}
对于FirebaseAnalytics
class。
禁用收集: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
构建变体,然后设置一个具有布尔值的变量。然后,您需要从扩展 application
的 java 文件中获取该值,即从启用 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
的值
public class 测试扩展应用程序 {
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
的值。希望这会有所帮助。
使用 Google Play Services 11.0,您现在可以在运行时禁用崩溃报告。
FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);
Recently 引入了以官方方式禁用 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"/>
...
public class MyApp extends Application {
public static boolean isDebuggable;
public void onCreate() {
super.onCreate();
isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
FirebaseCrash.setCrashCollectionEnabled(!isDebuggable);
}
}
当用户运行应用处于调试模式或发布模式时最简单的解决方案:
AndroidManifest.xml:
<meta-data
android:name="firebase_crash_collection_enabled"
android:value="${analytics_deactivated}"/>
build.gradle(Module:app)
buildTypes {
debug {
manifestPlaceholders = [analytics_deactivated: "false"]
}
release {
manifestPlaceholders = [analytics_deactivated: "true"]
}
}
因此,当应用程序处于 release 模式时,crashlatics 将被打开并且应用程序 运行s 在 debug 模式,它将被关闭。
我猜最近的 firebase crashlytics 有这个实现。
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)
我已经成功实现了 Firebase 崩溃报告,但是我需要在应用程序 运行 撤消 'debug' Build Variant 时禁用该服务,以避免控制台中的非真实崩溃开发中。
官方文档对此没有任何说明。
更新:
使用 Google Play Services / Firebase 11+,您现在可以在运行时禁用崩溃报告。 FirebaseCrash.setCrashCollectionEnabled()
(感谢@Tyler Carberry)
旧答案:
据社区推测,没有官方支持。我建议这样做的最佳方法是,在您的仪表板中设置多个 Firebase 应用程序,每个构建类型一个,并根据构建变体设置多个 google_services.json 文件指向每个不同的应用程序。
首先初始化gradle文件中的变量,检查是debug还是release模式。提交崩溃报告的最佳方式是在应用程序中 class.
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);
}
}
});
在我的应用程序 class 中,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 的处理程序
final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();
超出处理路径
受到 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/[包]/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());
我使用 versionCode
作为 local/production 构建的过滤器。
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 控制台中的崩溃报告。
您可以将 firebase 崩溃依赖项更改为仅发布依赖项。
为此,您将其定义为 releaseCompile 依赖项
releaseCompile 'com.google.firebase:firebase-crash:9.4.0'
现在它只会包含在发布版本中。如果您有其他需要崩溃报告的自定义构建类型,您可以将其添加到它们中。
customBuildTypeCompile 'com.google.firebase:firebase-crash:9.4.0'
目前您无法禁用 firebase 崩溃报告,但您可以停用 firebase 分析。
因此,一种方法是在同一 firebase 项目中创建另一个具有不同 ID 的应用程序。在此之后,您只需更改 appID 即可启用或禁用 firebase 崩溃报告。为了方便起见,我在下面创建了两个应用程序:
AppID:com.android - 对于发布构建类型
AppID:com.android.debug - 用于调试构建类型
更多详情请关注下方link:
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"
}
}
}
查看 link 了解更多详情:
https://developer.android.com/studio/build/application-id.html
编辑2:
基本上在上面的解决方案中,您在 Firebase 项目中制作了两个不同的应用程序,这样您就可以将开发和生产错误分开。
仅供参考 Firebase 崩溃报告已弃用。您应该使用 Fabrics Crashlytics(归 Google 所有)。它有一些非常酷的功能。
如前所述 - 没有官方方法可以做到这一点。但是@mark-d 提到的对我来说最糟糕的解决方法是重置 DefaultUncaughtExceptionHandler
(
但如果您只是按照建议调用 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;
}
我使用的简单易行的技巧是仅在 build.gradle
文件中的发布版本中添加 firebase 崩溃报告依赖项。
这将从调试构建类型中删除崩溃报告库,并仅将其添加到发布构建中。
dependencies {
releaseCompile 'com.google.firebase:firebase-crash:10.2.0'
}
对于FirebaseAnalytics
class。
禁用收集: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
构建变体,然后设置一个具有布尔值的变量。然后,您需要从扩展 application
的 java 文件中获取该值,即从启用 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
public class 测试扩展应用程序 {
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
的值。希望这会有所帮助。
使用 Google Play Services 11.0,您现在可以在运行时禁用崩溃报告。
FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);
Recently 引入了以官方方式禁用 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"/>
...
public class MyApp extends Application {
public static boolean isDebuggable;
public void onCreate() {
super.onCreate();
isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
FirebaseCrash.setCrashCollectionEnabled(!isDebuggable);
}
}
当用户运行应用处于调试模式或发布模式时最简单的解决方案:
AndroidManifest.xml:
<meta-data
android:name="firebase_crash_collection_enabled"
android:value="${analytics_deactivated}"/>
build.gradle(Module:app)
buildTypes {
debug {
manifestPlaceholders = [analytics_deactivated: "false"]
}
release {
manifestPlaceholders = [analytics_deactivated: "true"]
}
}
因此,当应用程序处于 release 模式时,crashlatics 将被打开并且应用程序 运行s 在 debug 模式,它将被关闭。
我猜最近的 firebase crashlytics 有这个实现。
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)