应用程序在调试时运行时如何禁用 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" />
在<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 不,该功能尚不可用
这是一个很好的解决方案,它基于禁用 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
:<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
可能的用途:
if (BuildConfig.DEBUG) //disable for debug
mFirebaseAnalytics.setAnalyticsCollectionEnabled(false);
Source
【讨论】:
【参考方案11】:首先,您必须创建 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
的值
公共类测试扩展应用程序
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 中的运行时运行时会失败?