Firebase存储 - StorageReference.getFile()在设备脱机时崩溃

时间:2016-10-03 19:32:19

标签: android firebase firebase-realtime-database firebase-storage

当我尝试使用方法StorageReference.getFile(File)从Firebase存储下载文件时,当设备脱机并达到超时时,它会崩溃。 Logcat在DynamicModulesC中显示NPE:

java.lang.NullPointerException: null reference
at asn.a(:com.google.android.gms.DynamiteModulesC:27)                                                                                     

相同的代码正常工作,并在互联网连接可用时下载文件。我已经在Android 4.1和6.0的设备和模拟器上进行了测试。 Firebase SDK版本9.6.1。 这是firebase SDK中的错误吗?我错过了什么吗?

简单代码:

FirebaseStorage firebaseStorage = FirebaseStorage.getInstance();
//firebaseStorage.setMaxDownloadRetryTimeMillis(15 * 1000);
StorageReference remoteDir= firebaseStorage.getReference().child("dir-with-files");
File destinationFile= new File("file-in-app-internal-storage");
StorageReference fileRef = remoteDir.child("file-from-firebase");
fileRef.getFile(destinationFile);

完整崩溃日志:

10-02 10:49:57.577 9429-9464/com.github.lecho.mobilization W/System: ClassLoader referenced unknown path: /system/priv-app/PrebuiltGmsCore/lib/x86_64
10-02 10:49:57.610 9429-9464/com.github.lecho.mobilization I/DynamiteModule: Considering local module com.google.android.gms.firebasestorage:0 and remote module com.google.android.gms.firebasestorage:1
10-02 10:49:57.610 9429-9464/com.github.lecho.mobilization I/DynamiteModule: Selected remote version of com.google.android.gms.firebasestorage, version >= 1
10-02 10:49:57.628 9429-9464/com.github.lecho.mobilization W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/m/00000002/n/x86_64

10-02 10:50:11.599 9429-9462/com.github.lecho.mobilization W/ExponenentialBackoff: network unavailable, sleeping.
10-02 10:50:11.599 9429-9462/com.github.lecho.mobilization E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.FirebaseApiNotAvailableException: firebase-auth is not linked, please fall back to unauthenticated mode.
10-02 10:50:12.234 9429-9464/com.github.lecho.mobilization W/ExponenentialBackoff: network unavailable, sleeping.
10-02 10:50:12.234 9429-9464/com.github.lecho.mobilization E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.FirebaseApiNotAvailableException: firebase-auth is not linked, please fall back to unauthenticated mode.

                                                                      --------- beginning of crash
10-02 10:50:12.236 9429-9464/com.github.lecho.mobilization E/AndroidRuntime: FATAL EXCEPTION: FirebaseStorage-Download-3
                                                                         Process: com.github.lecho.mobilization, PID: 9429
                                                                         java.lang.NullPointerException: null reference
                                                                             at asn.a(:com.google.android.gms.DynamiteModulesC:27)
                                                                             at bul.d(:com.google.android.gms.DynamiteModulesC:261)
                                                                             at buf.onTransact(:com.google.android.gms.DynamiteModulesC:76)
                                                                             at android.os.Binder.transact(Binder.java:387)
                                                                             at com.google.android.gms.internal.zzans$zza$zza.aE(Unknown Source)
                                                                             at com.google.android.gms.internal.zzanv.aE(Unknown Source)
                                                                             at com.google.firebase.storage.FileDownloadTask.run(Unknown Source)
                                                                             at com.google.firebase.storage.StorageTask$5.run(Unknown Source)
                                                                             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                             at java.lang.Thread.run(Thread.java:818)
10-02 10:50:12.237 1540-1997/system_process W/ActivityManager:   Force finishing activity com.github.lecho.mobilization/.ui.MainActivity

                                                           [ 10-02     10:50:12.246  1540: 1997 D/         ]
                                                           HostConnection::get() New Host Connection established 0x7f39f896fc00, tid 1997

3 个答案:

答案 0 :(得分:4)

事实证明这是Google Play服务中的一个错误。 Firebase团队已经修复了它。该修补程序适用于Google Play服务版 9.8.77

当设备离线时,现在StorageReference.getFile(File)不会使应用崩溃。相反,您将收到以下回复:

E/StorageException: StorageException has occurred. 
The operation retry limit has been exceeded. 
Code: -13030 HttpResult: -2

答案 1 :(得分:0)

试试这个:

try{
    fileRef.getFile(destinationFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
            // Local temp file has been created
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle any errors
        }
    });
} catch (Exception e){
// Error
}

此外,我们可以做以下事情: 1.在调用下载文件时添加try catch块来处理任何异常。 2.将存储引用保存为onSaveInstanceState中的引用。 3.稍后,我们可以调用onRestoreInstanceState。

StorageReference mStorageRef;  //mStorageRef was previously used to transfer data.

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // If there's a download in progress, save the reference so you can query it later
    if (mStorageRef != null) {
        outState.putString("reference", mStorageRef.toString());
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    // If there was a download in progress, get its reference and create a new StorageReference
    final String stringRef = savedInstanceState.getString("reference");
    if (stringRef == null) {
        return;
    }
    mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(stringRef);

    // Find all DownloadTasks under this StorageReference (in this example, there should be one)
    List tasks = mStorageRef.getActiveDownloadTasks();
    if (tasks.size() > 0) {
        // Get the task monitoring the download
        DownloadTask task = tasks.get(0);

        // Add new listeners to the task using an Activity scope
        task.addOnSuccessListener(this, new OnSuccessListener() {
          @Override
          public void onSuccess(DownloadTask.TaskSnapshot state) {
             handleSuccess(state); //call a user defined function to handle the event.
          }
        });
    }
}

答案 2 :(得分:-1)

您需要在使用getFile()方法联机后下载文件并在本地保存文件。一旦离线,请使用本地保存的文件。脱机时,无法使用getFile()方法下载文件。请阅读文档: https://firebase.google.com/docs/storage/android/download-files