我在应用启动时正在从Firebase存储中加载一些数据,我设置'onSuccessListener'和'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不会检查它是否具有Internet连接,仍然尝试启动任务。您不想自己启动上传/下载任务之前检查是否有互联网连接吗?
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;
}
编辑:
通常,您想在重新尝试加载数据时保持此功能。想象一下您的用户有Internet连接,但是它有点慢或不一致,并且FirebaseStorage
将设法通过第二次或第三次尝试开始下载任务的情况。
只有一个选项会影响FirebaseStorage
重试机制,在此进行描述:How to shorten Firebase storage download retrying period on Network Error或者,您可以执行我已经建议的操作,首先检查用户是否连接了互联网,然后才开始执行任务:
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
}