Reputation: 83
I am trying to retrieve an image from firebase storage for an android app by getting the download url of the image I want to retrieve in the onSuccessListener of the putImage call I used to upload the image in the first place. I am saving the download URL in a field variable but the issue is that the field variable is not being updated. I used toast to print out the value of the url field variable after my attempt in setting it equal to the download URl of the image I want to retrieve, but it remains unchanged. I'm not sure why this is the case so I would appreciate any help in resolving this.
//field variable that s meant to hold download url for the image I want to retrieve
String url = "never changed"
...
final String imageKey = UUID.randomUUID().toString();
StorageReference profileref = storageReference.child("contactProfiles/" + imageKey);
profileref.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> task = taskSnapshot.getMetadata().getReference().getDownloadUrl();
task.addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
//setting url equal to url of the image I want to retrieve
url = uri.toString();
}
});
Toast.makeText(ContactCreation.this, "Successful Profile Picture Upload", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(ContactCreation.this, "Failed to Upload Profile Picture", Toast.LENGTH_SHORT).show();
}
});
//Seeing if the url changed or not
Toast.makeText(ContactCreation.this, url, Toast.LENGTH_SHORT).show();
Upvotes: 1
Views: 678
Reputation: 600006
The call to getDownloadURL
makes a call to the server, and thus is executed asynchronously. This means that right now in your code, the Toast.makeText(ContactCreation.this, url
runs before the url = uri.toString()
ever runs, which explains why it logs no value.
The solution is always the same: any code that needs the value, needs to be inside the onSuccess
that is called with the value, or it needs to be called from there.
So:
task.addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
url = uri.toString();
Toast.makeText(ContactCreation.this, url, Toast.LENGTH_SHORT).show();
}
});
If you're new to such asynchronous behavior, I recommend reading some more about it. For example with:
Task
listeners.Upvotes: 2