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.