Firebase 未报告与 OkHttp 相关的崩溃

Posted

技术标签:

【中文标题】Firebase 未报告与 OkHttp 相关的崩溃【英文标题】:Firebase isn't reporting crashes related to OkHttp 【发布时间】:2018-03-18 22:09:40 【问题描述】:

我正在将我的代码从 Google 分析 迁移到 Firebase,解决我遇到的问题

    虽然使用的代码在所有情况下都相同,但一些自定义事件显示正确的值,而另一些则不显示。如果需要,可以提供代码。

更新:上面已经解决了,我正在发送大数据,所以它只是省略了它们。

    在使用 OkHttp(使用 android 网络库和 Asynctask)之前,firebase 在崩溃报告中显示正确的行号,但在使用 OkHttp 之后,我可以确认我已上传正确的映射文件,因为其他与 OKHttp 无关的崩溃报告正确。

所以我关心的不是例外,而是从哪里抛出的?

OKhttp 之前的 Firebase 崩溃报告

Exception java.net.SocketTimeoutException: connect timed out
java.net.PlainSocketImpl.socketConnect (PlainSocketImpl.java)
java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:334)
java.net.AbstractPlainSocketImpl.connectToAddress (AbstractPlainSocketImpl.java:196)
java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl.java:178)
java.net.SocksSocketImpl.connect (SocksSocketImpl.java:356)
java.net.Socket.connect (Socket.java:586)
com.android.okhttp.internal.Platform.connectSocket (Platform.java:113)
com.android.okhttp.Connection.connectSocket (Connection.java:1432)
com.android.okhttp.Connection.connect (Connection.java:1390)
com.android.okhttp.Connection.connectAndSetOwner (Connection.java:1667)
com.android.okhttp.OkHttpClient$1.connectAndSetOwner (OkHttpClient.java:133)
com.android.okhttp.internal.http.HttpEngine.connect (HttpEngine.java:466)
com.android.okhttp.internal.http.HttpEngine.sendRequest (HttpEngine.java:371)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute (HttpURLConnectionImpl.java:503)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse (HttpURLConnectionImpl.java:438)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode (HttpURLConnectionImpl.java:567)
com.package.MyClass$4.doInBackground (MyClass.java:168)
com.package.MyClass$4.doInBackground (MyClass.java:161)
android.os.AsyncTask$2.call (AsyncTask.java:304)
java.util.concurrent.FutureTask.run (FutureTask.java:237)
android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:243)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
java.lang.Thread.run (Thread.java:762)

OkHttp 之后的 Firebase 崩溃报告

Exception java.net.SocketTimeoutException: connect timed out
java.net.PlainSocketImpl.socketConnect (PlainSocketImpl.java)
java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:334)
java.net.AbstractPlainSocketImpl.connectToAddress (AbstractPlainSocketImpl.java:196)
java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl.java:178)
java.net.SocksSocketImpl.connect (SocksSocketImpl.java:356)
java.net.Socket.connect (Socket.java:586)
okhttp3.internal.platform.AndroidPlatform.connectSocket (AndroidPlatform.java:69)
okhttp3.internal.connection.RealConnection.connectSocket (RealConnection.java:238)
okhttp3.internal.connection.RealConnection.connect (RealConnection.java:158)
okhttp3.internal.connection.StreamAllocation.findConnection (StreamAllocation.java:256)
okhttp3.internal.connection.StreamAllocation.findHealthyConnection (StreamAllocation.java:134)
okhttp3.internal.connection.StreamAllocation.newStream (StreamAllocation.java:113)
okhttp3.internal.connection.ConnectInterceptor.intercept (ConnectInterceptor.java:42)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:147)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:121)
okhttp3.internal.cache.CacheInterceptor.intercept (CacheInterceptor.java:93)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:147)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:121)
okhttp3.internal.http.BridgeInterceptor.intercept (BridgeInterceptor.java:93)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:147)
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept (RetryAndFollowUpInterceptor.java:125)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:147)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:121)
okhttp3.RealCall.getResponseWithInterceptorChain (RealCall.java:200)
okhttp3.RealCall$AsyncCall.execute (RealCall.java:147)
okhttp3.internal.NamedRunnable.run (NamedRunnable.java:32)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
java.lang.Thread.run (Thread.java:761)

作为 OkHttp 实现的请求代码

Request request = new Request.Builder().url(Uri.parse(serviceUrl).buildUpon().appendPath("test").toString())
                .build();

        client.newCall(request).enqueue(new Callback() 
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) 
                    FirebaseCrash.report(e);
            

            @Override
            public void onResponse(@NonNull Call call, @NonNull final Response response) throws IOException 

【问题讨论】:

堆栈跟踪显示您开始使用 OkHttp 而不是 Android 的内置版本的 OkHttp。你在问什么? Android 从 lollipop 内部开始使用 Okhttp,因为我必须支持 4.0,所以我迁移到使用 Okhttp,正如您在上面的 logcat 中看到的崩溃位置被称为 MyClass,但在后者中没有当我明确使用 OKhttp 时的版本,我在问这是为什么? 请提供来源。在您使用堆栈跟踪中明确的异步任务之前。这个调用现在是如何实现的? 用代码更新了问题,虽然只是一个简单的调用,但我关心的不是异常,而是从哪里抛出的? 【参考方案1】:

在您的基础应用程序中使用以下代码初始化 crashlytics 后 (注意谷歌官方文档中缺少这部分)

FirebaseApp.initializeApp(getApplicationContext());
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true);

调用以下函数

FirebaseCrashlytics.getInstance().sendUnsentReports();

这样,您下次启动应用程序时,将上传未发送的报告

您可以使用此链接进行 crashlytics 集成 https://firebase.google.com/docs/crashlytics/get-started-new-sdk?platform=android&authuser=0

【讨论】:

哦,看在上帝的份上,谷歌! [用刘海把头撞在桌子上]。这怎么能少了?你是怎么知道这就是@shwetank 所需要的? 嘿,我从大学开始就对 android 开发完全陌生,所以我想我正在尽一切努力让这件事发挥作用。 Jetbrains IDE 提供了帮助,因为在任何地方都没有提到这个实例初始化,所以我寻找调用所有可以使用 FirebaseCrashlytics 实例调用的函数并且这个函数有效。 BDW 感谢您的赞赏,我很高兴它对您有用!【参考方案2】:

向您的 OkHttpClient 添加:

client.connectTimeoutMillis(20000);  // 20000 means 20 seconds give time here in milliseconds

或者您也可以将其添加到您的客户端构建器中:

clientBuilder.connectTimeout(60, TimeUnit.SECONDS);

发生这种情况是因为当服务器响应到达您时,您的请求超时。给你认为服务器响应可行的超时时间。

或者你也可以这样做,但我不确定:

Request request = new Request.Builder().wait(long millisecondshere).url(Uri.parse(serviceUrl).buildUpon().appendPath("test").toString())
                    .build();

【讨论】:

谢谢,但问题是使用 OkHttp 时没有提供崩溃的位置【参考方案3】:

这是超时问题,

有两种可能,

    您是否检查并测试了您的连接。 最好不要设置任何连接超时,如果您设置选择最大时间,因为它会引发错误,如果服务器在给定时间内没有响应..

防止SocketTimeoutException 超出了我们的限制......有效处理它的一种方法是定义连接超时,然后使用try catch 块处理它......希望这将有助于将来面临的任何人同样的问题。

您可以为 HttpUrlConnection 设置超时,例如,

HttpUrlConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(8000); 

【讨论】:

以上是关于Firebase 未报告与 OkHttp 相关的崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Crashlytics 集成未检测或报告崩溃

Firebase 崩溃日志未报告 IOS React Native 应用程序

iOS Firebase + Fabric Beta Crashylitics 未报告问题

来自 Firebase 的数据未显示在 BigQuery/Data Studio 中

Firebase pod 更新未更新

Firebase 可选崩溃未正确显示