John Green
John Green

Reputation: 83

Why can't this retieve the download URL of an image on Firebase Storage?

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

Answers (1)

Frank van Puffelen
Frank van Puffelen

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:

Upvotes: 2

Related Questions