简体   繁体   中英

Problem in uploading url of mutiple files to Firestore - Android

I am trying to upload multiple files to firebase storage and their urls to Firestore using a for loop. If I try to upload 3 files,then all 3 are uploaded to the firebase storage but the url of only the first file is added to Firestore. I don't see any problem in my for loop as such, so how should I fix this?

 @Override
 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
     super.onActivityResult(requestCode, resultCode, data);

     if (requestCode == 101 && resultCode == RESULT_OK) {

         final String folderName = intent.getStringExtra("folderName");

         if (data.getClipData() != null) {
             //multiple files

             int numItemSelected = data.getClipData().getItemCount();

             for (int i = 0; i < numItemSelected; i++) {

                 Uri pdfUri = data.getClipData().getItemAt(i).getUri();
                 fileName = getFileName(pdfUri);

                 pdfNameList.add(fileName);
                 pdfUrlList.add(pdfUri.toString());

                 StorageReference pdfRef = storageReference.child(folderName + "/" + fileName);
                 pdfRef.putFile(pdfUri)
                     .addOnSuccessListener(new OnSuccessListener < UploadTask.TaskSnapshot > () {
                         @Override
                         public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                             Toast.makeText(MainActivity.this, "File Uploaded!", Toast.LENGTH_SHORT).show();

                             Task < Uri > uriTask = taskSnapshot.getStorage().getDownloadUrl();
                             while (!uriTask.isComplete());
                             Uri uri = uriTask.getResult();

                             Map < String, Object > map = new HashMap < > ();
                             map.put("url", String.valueOf(uri));
                             map.put("name", fileName);
                             DocumentReference documentReference =
                                 db.collection(folderName).document(fileName);

                             documentReference.set(map)
                                 .addOnSuccessListener(new OnSuccessListener < Void > () {
                                     @Override
                                     public void onSuccess(Void aVoid) {
                                         Log.d("TEST", "onSuccess: Task was  successful");

                                     }
                                 })
                                 .addOnFailureListener(new OnFailureListener() {
                                     @Override
                                     public void onFailure(@NonNull Exception e) {
                                         Log.d("TEST", "onFailure: Task was not successful" +
                                             e.getLocalizedMessage() + "  " + e.getMessage());
                                     }
                                 });

                         }
                     })
                     .addOnFailureListener(new OnFailureListener() {
                         @Override
                         public void onFailure(@NonNull Exception e) {
                             Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                         }
                     });


             }
             Log.d("size", "onActivityResult: " + pdfNameList.size()); //logs the correct size

         } else if (data.getData() != null) {
             //selected single file
             //working code,skipped from here   

         }

     }
 }

Edit: Only the last document is being uploaded to Firestore. If I am uploading two files then the value of i (variable of for loop ) is 2 just after putting strings in my map

Edit: My problem is similar to this , but I can't seem to understand the solution

The problem is that you are doing multiple sequenced asynchronous operations (upload to Storage and adding data to firestore) in a synchronous way in your loop and that causes the following behavior (example):

The second upload to Storage triggers before the first operation to Firestore has been completed, and this causes the fileName variable that is being used for the Firestore operation to be populated with value of the next upload.

My suggestion to fix the issue you are facing would be to either not do the operations in sequence, eg. upload everything into storage and only then add everything to firestore, or populate the part of your map that depends on the filename variable right after it's value has been populated and not in the onSuccess handler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM