在 Firebase Storage Android 中下载 Imageuri 的问题

Posted

技术标签:

【中文标题】在 Firebase Storage Android 中下载 Imageuri 的问题【英文标题】:Problem in download Imageuri in Firebase Storage Android 【发布时间】:2021-07-07 19:16:27 【问题描述】:

我正在从我的应用上传图片并将下载 URL 存储在模型类中,但在看到 URL 后,我复制了它并粘贴了链接,但它没有打开图片。

这是 Firebase 实时数据库图片

这是 Firebase 存储

这里应该是什么 https://firebasestorage.googleapis.com/v0/b/myapp-not-final.appspot.com/o/uploads%2F1618234721167.jpg?alt=media&token=fcac1404-87ce-4c7d-ae5f-a1ec7074bf04

Java 文件

Upload_Fragment.java

public class Upload_Fragment extends Fragment 
    private static final int PICK_IMAGE_REQUEST = 10;
    private ImageView uploadImageView;
    private Uri mImageUri;
    private StorageReference storageReference;
    private DatabaseReference databaseReference;
    private StorageTask mUploadTask;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_upload, container, false);
        Button chooseImageButton = view.findViewById(R.id.upload_image_button);
        Button uploadImageButton = view.findViewById(R.id.done_button);
        uploadImageView = view.findViewById(R.id.upload_image_view);
        FirebaseStorage storage = FirebaseStorage.getInstance();
        storageReference = storage.getReference("uploads");
        databaseReference = FirebaseDatabase.getInstance().getReference("uploads");
        chooseImageButton.setOnClickListener(v -> openFileChooser());
        uploadImageButton.setOnClickListener(v -> 
            if (mUploadTask != null && mUploadTask.isInProgress()) 
                Toast.makeText(getActivity(), "Upload in Progress", Toast.LENGTH_SHORT).show();

             else 
                uploadToFirebase(mImageUri);
            


        );

        return view;
    

    private void openFileChooser() 
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, PICK_IMAGE_REQUEST);
    

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
                && data != null && data.getData() != null) 
            mImageUri = data.getData();
            Picasso.get().load(mImageUri).into(uploadImageView);

        
    

    private String getFileExtension(Uri uri) 

        ContentResolver contentResolver = Objects.requireNonNull(getActivity()).getContentResolver();
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        return mime.getExtensionFromMimeType(contentResolver.getType(uri));
    

    private void uploadToFirebase(Uri mImageUri) 
        if (mImageUri != null) 
            final ProgressDialog progressDialog = new ProgressDialog(getActivity());
            progressDialog.setTitle("Uploading...");
            progressDialog.show();

            StorageReference reference = storageReference.child(System.currentTimeMillis()
                    + "." + getFileExtension(mImageUri));
            reference.putFile(mImageUri)
                    .addOnSuccessListener(taskSnapshot -> 
                        progressDialog.dismiss();
                        Toast.makeText(getActivity(), "Saved Succesfully", Toast.LENGTH_SHORT).show();
                        reference.getDownloadUrl()
                                .addOnSuccessListener(uri -> 
                                    Upload upload = new Upload(mImageUri.toString());
                                    String uploadId = databaseReference.push().getKey();
                                    databaseReference.child(uploadId).setValue(upload);
                                );
                    )
                    .addOnProgressListener(snapshot -> 
                        double progress = (100.0 * snapshot.getBytesTransferred() / snapshot
                                .getTotalByteCount());
                        progressDialog.setMessage("Uploaded " + (int) progress + "%");
                    )
                    .addOnFailureListener(e -> 
                        progressDialog.dismiss();
                        Toast.makeText(getActivity(), "Error Ocurred" + e.getMessage(), Toast.LENGTH_SHORT).show();
                    );


        
    

Upload.java //这是模型类

public class Upload 
    private String mImageUrl;


    public Upload() 

    

    public Upload(String imageUrl) 
        mImageUrl = imageUrl;
    

    public String getmImageUrl() 
        return mImageUrl;
    

    public void setmImageUrl(String mImageUrl) 
        this.mImageUrl = mImageUrl;
    

【问题讨论】:

能分享一下日志吗?它将帮助我们给出准确的解决方案。 【参考方案1】:

uploadToFirebase方法里面

reference.getDownloadUrl().addOnSuccessListener(uri -> .....

而不是mImageUri.toString(),而是按照下面的uri.toString()。所以你会得到实际的网址并解决你的问题。

private void uploadToFirebase(Uri mImageUri) 
        if (mImageUri != null) 
            final ProgressDialog progressDialog = new ProgressDialog(getActivity());
            progressDialog.setTitle("Uploading...");
            progressDialog.show();

            StorageReference reference = storageReference.child(System.currentTimeMillis()
                    + "." + getFileExtension(mImageUri));
            reference.putFile(mImageUri)
                    .addOnSuccessListener(taskSnapshot -> 
                        progressDialog.dismiss();
                        Toast.makeText(getActivity(), "Saved Succesfully", Toast.LENGTH_SHORT).show();
                        reference.getDownloadUrl()
                                .addOnSuccessListener(uri -> 
                                    Upload upload = new Upload(uri.toString());
                                    String uploadId = databaseReference.push().getKey();
                                    databaseReference.child(uploadId).setValue(upload);
                                );
                    )
                    .addOnProgressListener(snapshot -> 
                        double progress = (100.0 * snapshot.getBytesTransferred() / snapshot
                                .getTotalByteCount());
                        progressDialog.setMessage("Uploaded " + (int) progress + "%");
                    )
                    .addOnFailureListener(e -> 
                        progressDialog.dismiss();
                        Toast.makeText(getActivity(), "Error Ocurred" + e.getMessage(), Toast.LENGTH_SHORT).show();
                    );


        
    

【讨论】:

它解决了我的问题,但我想问一件事,如果我将 mImageUrl 更改为 uri,那么我必须在模型类中进行哪些更改,以便稍后检索图像 无需对模型类进行任何更改。这里mImageUri.toString() 将为您提供图像内容地址,而您需要图像的https 地址,因此您可以通过uri.toString() 获取它并使用此检索图像相同的网址。 我在回收站视图中看不到任何图像你能帮我解决这个问题吗,这里是 *** 链接***.com/questions/67073457/…【参考方案2】:

在您的数据库架构中,您的“mImageUrl”属性包含一个类似于此的 URL:

content://com.android.externalstorage.documents...

您可能会看到,这些 URL 指向位于外部存储本地的一些文件。因此,您不能使用此类 URL 并期望从 Firebase 存储中读取数据。要在 Firebase 控制台中检查图像的 URL,请在右侧查看名为“文件位置”的部分。如果您单击令牌,您将获得类似于此的图像 URL 的副本:

https://firebasestorage.googleapis.com/v0/b/myapp-not-final.appspot.com/...

这意味着这是应该存储在数据库中的正确 URL,而 不是本地的。要获取下载 URL,请查看我在以下帖子中的回答:

How to get the download url from Firebase Storage?

获得正确的 URL 后,将其添加到 Firestore,以便日后使用。

【讨论】:

以上是关于在 Firebase Storage Android 中下载 Imageuri 的问题的主要内容,如果未能解决你的问题,请参考以下文章

React Redux Firebase 无法获取 firebase.storage

Firebase 上传多个 Storage/Firestore

firebase.storage() 不是 JavaScript 中的函数

用于 firebase_storage 的 Flutter OnProgressListener?

如何在图像插入firebase.storage后获取下载URL

Vuejs + Firebase Storage 将多个图像上传到 Firebase Storage 并将所有 downloadURL 推送到 Firestore