【问题标题】:Get multiple download URL from firebase storage and save them to firebase firestore从 firebase 存储中获取多个下载 URL 并将它们保存到 firebase firestore
【发布时间】:2019-05-15 14:38:11
【问题描述】:

我已成功将多个选定的音频文件上传到 Firebase 存储,并且我能够检索所有这些文件的 URL。由于我必须上传多个文件,因此我使用 for 循环来执行此操作。上传文件并检索 URL 后,我想将它们保存到 firestore,这就是我为此所做的。

上传文件功能

private void uploadAudioFiles(List<Uri> list, final Map<String, String> hashMap) {
        if (list.size() > 0){
            for (int a=0; a<list.size(); a++){
                Uri perFile = list.get(a);
                String filename = getSelectedFileName(perFile);
                final StorageReference audioFileReference = referenceFolder.child("audioClipData/"+filename);
                final int finalA = a;
                audioFileReference.putFile(perFile).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        audioFileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                            @Override
                            public void onSuccess(Uri uri) {
                                hashMap.put("audioFile"+ finalA, String.valueOf(uri));
                                Log.e("APP_LOG:HashMap(AudioA)", String.valueOf(hashMap));
                            }
                        });
                    }
                });
            }
        }
    }

点击保存按钮

下面是调用uploadAudioFiles()函数的代码。

Map<String, String> hashMap = new HashMap<>();
    String username = name.getText().toString();
            if (!username.isEmpty()){
                progressDialog.show();
                hashMap.put("username", username);
                uploadAudioFiles(audioClipList, hashMap);


                Log.e("APP_LOG:HashMapFINAL", hashMap.toString());
                firestore.collection(currentUser.getUid()).add(hashMap).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                    @Override
                    public void onSuccess(DocumentReference documentReference) {
                        progressDialog.dismiss();
                    }
                });
            }else {
                name.setError("Required");
            }

这是我在 uploadAudioFiles() 函数中得到的日志

E/APP_LOG:HashMap(AudioA): {username=Abhi, audioFile0=https://firebasestorage.googleapis.com/v0/b/myapp.appspot.com/o/linktofile}

这是我在 uploadAudioFiles() (ButtonClick) 函数之外得到的日志

E/APP_LOG:HashMapFINAL: {username=Abhi}

现在我不明白为什么当我在uploadfile 函数中和在uploadfile 函数之外时HashMap 是不同的。这是因为 for 循环的范围还是其他原因?

有人可以帮我了解情况和解决方法吗?

【问题讨论】:

    标签: android firebase hashmap google-cloud-firestore firebase-storage


    【解决方案1】:

    Firebase API 是异步的,会在工作完成前立即返回。只要上传完成并且下载 URL 已知,您的 HashMap 就会随着时间而改变。如果你想知道所有的上传什么时候完成,并且知道所有的下载地址,你需要关注它们返回的Task对象。现在,您的 uploadAudioFiles 函数将在任何工作完成之前立即返回,并且在它之后运行的代码将在一段时间后才能看到任何结果。

    【讨论】:

      【解决方案2】:

      这是我想做的新代码!

      private void executeUpload(final Map<String, String> hashMap, final List<Uri> uriList) {
              if (uriList.size() > 0){
                  spotDialog.show();
                      int counter = 0;
                      final String firebasePushID = firestore.collection(currentUser.getUid()).document().getId();
                      for (int i=0;i<uriList.size(); i++){
                          Uri perFile = uriList.get(i);
                          counter++;
                          final int finalCounter = counter;
                          final int finalI = i;
                          storageReference.child(firebasePushID).putFile(perFile).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                              @Override
                              public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                                  if (task.isSuccessful()){
                                      storageReference.child(firebasePushID).getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                                          @Override
                                          public void onComplete(@NonNull Task<Uri> task) {
                                              if (task.isSuccessful()){
                                                  String uri = String.valueOf(task.getResult());
                                                  Log.e(LOGCODE, uri);
                                                  hashMap.put(fileName, uri);
                                                  if (!(finalCounter < uriList.size())){
                                                      firestore.collection(currentUser.getUid()).add(hashMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
                                                          @Override
                                                          public void onComplete(@NonNull Task<DocumentReference> task) {
                                                              if (task.isSuccessful()){
                                                                  clearFormData();
                                                                  spotDialog.dismiss();
                                                                  Log.e(LOGCODE, hashMap.toString());
                                                                  Toast.makeText(MainActivity.this, "Saved data successfully.", Toast.LENGTH_SHORT).show();
                                                              }else {
                                                                  Log.e(LOGCODE, Objects.requireNonNull(task.getException()).getMessage());
                                                                  spotDialog.dismiss();
                                                                  Toast.makeText(MainActivity.this, "Couldn't save data! Data seems to be lost in space :(", Toast.LENGTH_SHORT).show();
                                                              }
                                                          }
                                                      });
                                                  }
                                              }else {
                                                  spotDialog.dismiss();
                                                  Log.e(LOGCODE, Objects.requireNonNull(task.getException()).getMessage());
                                                  Toast.makeText(MainActivity.this," File uploaded but lost in space :(", Toast.LENGTH_SHORT).show();
                                              }
                                          }
                                      });
                                  }else{
                                      spotDialog.dismiss();
                                      Log.e(LOGCODE, Objects.requireNonNull(task.getException()).getMessage());
                                      Toast.makeText(AddTransaction.this, "Couldn't upload file ", Toast.LENGTH_SHORT).show();
                                  }
                              }
                          });
                      }
              }
          }
      

      我想做什么?

      首先,将用户名添加到hashmap,然后上传AudioFiles,然后将这些文件的URL存储到hashmap,然后将其保存到firestore。

      旧代码有问题?

      编写旧代码是为了将 audioFiles 存储到 FirebaseStorage,然后将其 URL 存储到 firestore,但不幸的是,旧代码并没有发生这种情况。

      问题背后的原因:- firebase API 是异步的,为了让一切按顺序正常工作,我必须等到所有文件都上传完毕,并将其 URL 保存到 hashmap 中。由于我的代码不是为了等待任何东西而编写的,它只是调用“uploadAudioFiles”函数,然后不等待响应,它曾经到达函数的末尾。这就是我的 hashmap 为空的原因。直到我尝试将 hashmap 保存到 firestore 时文件才上传,因此 hashmap 为空。

      我是如何解决我的问题的?

      在旧代码中,我调用了用于将文件上传到 FirebaseStorage 的 uploadAudioFunction,但它不是为了将 hashmap 保存到 firestore。因此,我基本上重新编写了处理文件上传以及处理将哈希图保存到 Firestore 的函数。我使用了一个计数器变量来计算 for 循环是否已经旋转到我的列表末尾。使用该计数器变量,我编写了一个 if...else 条件,说明循环是否已旋转所需的次数,然后将 hashmap 数据保存到 firestore。这样,我就可以等到所有文件都上传并且它们的 URL 被保存到 hashmap 中。

      警告:- 这不是最好的方法。有时 hashmap 不会 包含最后一个文件 URL,但文件已成功上传。这就是我目前所得到的一切,但我仍在努力寻找一种新的有效方法来完成这项工作。如果您有更好的方法,请告诉我。

      【讨论】:

        猜你喜欢
        • 2021-03-14
        • 2019-11-15
        • 2021-10-01
        • 2021-03-21
        • 2019-04-30
        • 1970-01-01
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多