Firebase存储没有互联网连接回调



当应用程序开始时,我正在从firebase存储加载一些数据,我正在设置"onSuccessListener"one_answers"onFailureListener"以在加载完成时隐藏进度条。问题是:当我离线试用该应用程序时,根本不会收到任何回调。我尝试了"onCompleteListener",但它也没有被调用它在控制台中给我以下消息:

W/ManagedChannelImpl: [{0}] Failed to resolve name. status={1}
W/Firestore: (21.4.1) [OnlineStateTracker]: Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: Status{code=UNAVAILABLE, description=Unable to resolve host firestore.googleapis.com, cause=java.lang.RuntimeException: java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
at io.grpc.internal.DnsNameResolver.resolveAll(DnsNameResolver.java:420)
at io.grpc.internal.DnsNameResolver$Resolve.resolveInternal(DnsNameResolver.java:256)
at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:213)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:157)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
at io.grpc.internal.DnsNameResolver$JdkAddressResolver.resolveAddress(DnsNameResolver.java:640)
at io.grpc.internal.DnsNameResolver.resolveAll(DnsNameResolver.java:388)
at io.grpc.internal.DnsNameResolver$Resolve.resolveInternal(DnsNameResolver.java:256) 
at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:213) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:764) 
Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
at libcore.io.Linux.android_getaddrinfo(Native Method)
at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:172)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:137)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105) 
at java.net.InetAddress.getAllByName(InetAddress.java:1154) 
at io.grpc.internal.DnsNameResolver$JdkAddressResolver.resolveAddress(DnsNameResolver.java:640) 
at io.grpc.internal.DnsNameResolver.resolveAll(DnsNameResolver.java:388) 
at io.grpc.internal.DnsNameResolver$Resolve.resolveInternal(DnsNameResolver.java:256) 
at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:213) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:764) 
}
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.

然后这些消息,只要应用程序正在运行:

W/ExponenentialBackoff: network unavailable, sleeping.
W/ExponenentialBackoff: network unavailable, sleeping.
W/ExponenentialBackoff: network unavailable, sleeping.
W/ExponenentialBackoff: network unavailable, sleeping.
W/ExponenentialBackoff: network unavailable, sleeping.
W/ExponenentialBackoff: network unavailable, sleeping.
W/ExponenentialBackoff: network unavailable, sleeping.
.
.
.

在等待了这么长时间后,它终于给出了一个错误并启动了"失败侦听器":

E/StorageException: StorageException has occurred.
The operation retry limit has been exceeded.
Code: -13030 HttpResult: -2
E/StorageException: Could not open resulting stream.
java.io.IOException: Could not open resulting stream.
at com.google.firebase.storage.StreamDownloadTask.createDownloadStream(com.google.firebase:firebase-storage@@19.1.1:145)
at com.google.firebase.storage.StreamDownloadTask.access$000(com.google.firebase:firebase-storage@@19.1.1:36)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:167)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:164)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.ensureStream(com.google.firebase:firebase-storage@@19.1.1:325)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.access$100(com.google.firebase:firebase-storage@@19.1.1:262)
at com.google.firebase.storage.StreamDownloadTask.run(com.google.firebase:firebase-storage@@19.1.1:175)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage@@19.1.1:1072)
at com.google.firebase.storage.StorageTask$$Lambda$12.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
E/StorageException: StorageException has occurred.
The operation retry limit has been exceeded.
Code: -13030 HttpResult: -2
E/StorageException: Could not open resulting stream.
java.io.IOException: Could not open resulting stream.
at com.google.firebase.storage.StreamDownloadTask.createDownloadStream(com.google.firebase:firebase-storage@@19.1.1:145)
at com.google.firebase.storage.StreamDownloadTask.access$000(com.google.firebase:firebase-storage@@19.1.1:36)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:167)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:164)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.ensureStream(com.google.firebase:firebase-storage@@19.1.1:325)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.access$100(com.google.firebase:firebase-storage@@19.1.1:262)
at com.google.firebase.storage.StreamDownloadTask.run(com.google.firebase:firebase-storage@@19.1.1:175)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage@@19.1.1:1072)
at com.google.firebase.storage.StorageTask$$Lambda$12.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
W/Warning: Maybe internet or authentication issues
com.google.firebase.storage.StorageException: The operation retry limit has been exceeded.
at com.google.firebase.storage.StreamDownloadTask.snapStateImpl(com.google.firebase:firebase-storage@@19.1.1:229)
at com.google.firebase.storage.StreamDownloadTask.snapStateImpl(com.google.firebase:firebase-storage@@19.1.1:35)
at com.google.firebase.storage.StorageTask.snapState(com.google.firebase:firebase-storage@@19.1.1:343)
at com.google.firebase.storage.TaskListenerImpl.onInternalStateChanged(com.google.firebase:firebase-storage@@19.1.1:85)
at com.google.firebase.storage.StorageTask.tryChangeState(com.google.firebase:firebase-storage@@19.1.1:390)
at com.google.firebase.storage.StorageTask.tryChangeState(com.google.firebase:firebase-storage@@19.1.1:426)
at com.google.firebase.storage.StreamDownloadTask.run(com.google.firebase:firebase-storage@@19.1.1:201)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage@@19.1.1:1072)
at com.google.firebase.storage.StorageTask$$Lambda$12.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.io.IOException: Could not open resulting stream.
at com.google.firebase.storage.StreamDownloadTask.createDownloadStream(com.google.firebase:firebase-storage@@19.1.1:145)
at com.google.firebase.storage.StreamDownloadTask.access$000(com.google.firebase:firebase-storage@@19.1.1:36)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:167)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:164)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.ensureStream(com.google.firebase:firebase-storage@@19.1.1:325)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.access$100(com.google.firebase:firebase-storage@@19.1.1:262)
at com.google.firebase.storage.StreamDownloadTask.run(com.google.firebase:firebase-storage@@19.1.1:175)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage@@19.1.1:1072) 
at com.google.firebase.storage.StorageTask$$Lambda$12.run(Unknown Source:2) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:764) 

我想在这种情况发生时尽快收到回拨。

您确实收到了一个失败回调,但原因是ERROR_RETRY_LIMIT_EXCEEDED。看起来FirebaseStorage没有检查它是否有互联网连接,仍然试图启动任务。你不想在自己开始上传/下载任务之前检查一下是否有互联网连接吗?

public static boolean isOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int     exitValue = ipProcess.waitFor();
return (exitValue == 0);
}
catch (IOException | InterruptedException e) { e.printStackTrace(); }
return false;
}

编辑:

通常,您希望在重新加载数据时保持此功能。想象一下这样一种情况,当您的用户有一个互联网连接,但它有点慢或不一致,FirebaseStorage将设法通过第二次或第三次尝试启动下载任务。

只有一个选项可以影响FirebaseStorage重试机制,这里介绍:如何缩短网络错误时Firebase存储下载重试周期
或者你可以按照我的建议,先检查用户是否有互联网连接,然后再开始任务:

void yourMethod(...) {
if (!isOnline) {
//hiding progress bar
//and fallback, maybe Toast to inform the user about the issue with internet connection
return;
}
// start your download task
}

最新更新