简体   繁体   中英

How to retrieve the download URL of an image from Firebase Storage?

I am watching an old tutorial about Firebase Storage. The getDownloadUrl() method from UploadTask.TaskSnapshot is no longer existent, and the documentation fails to be clear to me.

What I've implemented so far is the upload process and I can confirm it works, but getting the URL is a pain and I can't make the way they explain how to do it because:

1) Creating a Task<Uri> urlTask = uploadTask.add[...]() will result in the following error on the IDE:

在此处输入图片说明

I don't understand because it is specified in the docs.

2) Using reference.getDownloadUrl() will display a different URL compared to what is shown on the console when seeing the details of the uploaded image. The download URL the console shows is

https://firebasestorage.googleapis.com/v0/b/chatroom-e44e6.appspot.com/o/chat_photos%2F73185640?alt=media&token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

while logging will show

com.google.android.gms.tasks.xxx@xxxxxxx

My full code at the moment:

if (requestCode == RC_PHOTO_PICKER) {
    if (data != null) {
        Toast.makeText(MainActivity.this, "Uploading...", Toast.LENGTH_SHORT).show();

        Uri file = data.getData();
        final StorageReference reference = mPhotoStorageReference.child(file.getLastPathSegment());
        UploadTask upload = reference.putFile(file);

        upload.addOnFailureListener(this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(MainActivity.this, "Image could not be uploaded: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }).addOnCompleteListener(this, new OnCompleteListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                ChatroomMessage message = new ChatroomMessage(null, mUsername, reference.getDownloadUrl().toString()); // <- com.google.android.gms.tasks.xxx@xxxxxxx
                mMessagesDatabaseReference.push().setValue(message);
                Toast.makeText(MainActivity.this, "Image uploaded!", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

My app already has Firebase UI implemented to handle login operations, and the rules are

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

I put the effort and wasted more time but here is the more generic and working solution

    private void uploadImage() {

    if (filePath != null) {
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setTitle("Uploading...");
        progressDialog.show();
        final StorageReference ref = storageReference.child("images/" +currentFirebaseUser.getUid() + "");

        ref.putFile(filePath)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        progressDialog.dismiss();

                        Task<Uri> urlTask = taskSnapshot.getStorage().getDownloadUrl();
                        while (!urlTask.isSuccessful());
                        Uri downloadUrl = urlTask.getResult();
                        Log.e("uri12",downloadUrl+"This is uri of image download");
                        Toast.makeText(AddItemActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        progressDialog.dismiss();
                        Toast.makeText(AddItemActivity.this, "Failed " + e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                })
                .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                        double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot
                                .getTotalByteCount());
                        progressDialog.setMessage("Uploaded " + (int) progress + "%");
                    }
                });
    }
}

You have Permission denied error it means you don't have permision for access data from firebase. Please check here

在此处输入图片说明

if your security rules is defined public then here is no need for permission and if it isn't public or secured then you need to login by auth before you getting data from firebase and if login success then you can continue your work.

check this it will help you to understanding firebase security rules.

After many attempts, I managed to solve it. This is the implementation:

Uri file = data.getData();
final StorageReference reference = mPhotoStorageReference.child(file.getLastPathSegment());
UploadTask upload = reference.putFile(file);

upload.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        Toast.makeText(MainActivity.this, "Image could not be uploaded: " + e.getMessage(), Toast.LENGTH_LONG).show();
    }
});

upload.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
    @Override
    public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
        if (!task.isSuccessful()) {
            throw task.getException();
        }

        return reference.getDownloadUrl();
    }
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
    @Override
    public void onComplete(@NonNull Task<Uri> task) {
        if (task.isSuccessful()) {
            Uri downloadUrl = task.getResult();
            ChatroomMessage message = new ChatroomMessage(null, mUsername, downloadUrl.toString());

            mMessagesDatabaseReference.push().setValue(message);

            Toast.makeText(MainActivity.this, "Image uploaded!", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
        }
    }
});

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