【问题标题】:Retrieving image from Firebase Storage从 Firebase 存储中检索图像
【发布时间】:2020-10-23 02:35:26
【问题描述】:

我知道这是一个讨论的话题,但我在这里,毕竟我找到的所有其他解决方案都没有解决我的问题。我在 Firebase 存储中保存了多张图片,现在我想获取其中一张并将其放入 AlertDialog(或其他 Activity)上的 ImageView。

我已阅读有关 Glide 解决方案的信息,但它对我不起作用。吉尔德:

Glide.with(ViewScenesSG.this) //ViewScenesSG is the Activity
                .load(reference) //the storage reference
                .into(imageView); //my imageView

Glide 的依赖项(我已经尝试了多个版本,并且 4.8.0 是唯一没有给我构建错误的版本):

implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
annotationProcessor 'androidx.annotation:annotation:1.1.0'

我还阅读了有关.using(new FirebaseImageLoader()) 方法的信息,我已经实现了FirebaseImageLoader(),但是找不到using() 方法=> 构建错误。我相信它已被删除。

我试过的第二个版本是这个(在另一个问题here中找到):

final long ONE_MEGABYTE = 1024 * 1024;
       reference.getBytes(ONE_MEGABYTE)
           .addOnSuccessListener(new OnSuccessListener<byte[]>() {
               @Override
               public void onSuccess(byte[] bytes) {
                   Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                   DisplayMetrics dm = new DisplayMetrics();
                   getWindowManager().getDefaultDisplay().getMetrics(dm);
                   
                   imageView.setMinimumHeight(dm.heightPixels);
                   imageView.setMinimumWidth(dm.widthPixels);
                   imageView.setImageBitmap(bm);
               }
           }).addOnFailureListener(new OnFailureListener() {
           @Override
           public void onFailure(@NonNull Exception exception) {
               Toast.makeText(ViewScenesSG.this, "Couldn't retrieve image.", Toast.LENGTH_SHORT).show();
           }
       });

但每次它都在失败侦听器上进行。因此,我的 imageView 始终为空。

在我的 logcat 中,我发现了这个错误:

E/StorageException: Could not open resulting stream.
    java.io.IOException: Could not open resulting stream.
        at com.google.firebase.storage.StreamDownloadTask.createDownloadStream(com.google.firebase:firebase-storage@@19.1.1:145)
        at com.google.firebase.storage.StreamDownloadTask.access$000(com.google.firebase:firebase-storage@@19.1.1:36)
        at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:167)
        at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage@@19.1.1:164)
        at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.ensureStream(com.google.firebase:firebase-storage@@19.1.1:325)
        at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.access$100(com.google.firebase:firebase-storage@@19.1.1:262)
        at com.google.firebase.storage.StreamDownloadTask.run(com.google.firebase:firebase-storage@@19.1.1:175)
        at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage@@19.1.1:1072)
        at com.google.firebase.storage.StorageTask$$Lambda$12.run(Unknown Source:2)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)
E/StorageException: StorageException has occurred.
    Object does not exist at location.
     Code: -13010 HttpResult: 404

但是图像在那里,在存储中,并且引用直接指向它:

storageRef = storage.getReference("photos").child(title); //for all images in the current folder named with the 'title' attribute
StorageReference reference = storageRef.child(imageName); //for the image I want to retrieve

我错过了什么?

编辑:使用评论中的建议,我尝试了:

reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                Glide.with(ViewScenesSG.this)
                        .load(uri.toString())
                        .into(imageView);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(ViewScenesSG.this, "Retrieving image failed",
                        Toast.LENGTH_SHORT).show();
            }
        });

但这次我得到了错误:

E/StorageException: {  "error": {    "code": 404,    "message": "Not Found.  Could not get object",    "status": "GET_OBJECT"  }}
    java.io.IOException: {  "error": {    "code": 404,    "message": "Not Found.  Could not get object",    "status": "GET_OBJECT"  }}
        at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@19.1.1:433)
        at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@19.1.1:450)
        at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage@@19.1.1:441)
        at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:272)
        at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:286)
        at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:70)
        at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:62)
        at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage@@19.1.1:76)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

【问题讨论】:

  • 新的错误消息意味着reference 没有指向 Firebase 存储中的现有图像。您需要检查如何初始化 reference 并确保它所引用的图像存在。
  • 参考指向正确,我检查了日志。

标签: android firebase imageview firebase-storage


【解决方案1】:

我发现了以下solution(如之前在cmets中所建议的):

使用带有 Gilde 的 Firebase UI 插件,我添加了以下依赖项:

implementation 'com.firebaseui:firebase-ui-storage:6.2.0'

现在,StorageReference reference 指向图像,ImageView 必须在其中上传内容,以下代码检索图像并将其放入ImageView:

Glide.with(ViewScenesSG.this)  //this is the current Activity
                .load(reference)
                .into(imageView);

值得一提的是,ImageView 必须将 dimensions 设置为特定值,而不是使用 wrap_content 或 match_parent(至少在我的情况下是高度),否则它将显示为一个小图标。这也可能取决于图像之前在存储中的保存方式。

希望这对其他人也有帮助!

【讨论】:

    【解决方案2】:

    我不确定您的第二个 sn-p 中出了什么问题,但在第一个 sn-p 中您似乎将 StorageReference 传递给 Glide。由于 Glide 对 Firebase 存储一无所知,因此这行不通。

    相反,您应该从 Firebase Storage 获取下载 URL,这是一个常规 HTTPS URL,提供对数据的公共访问,并将其传递给 Glide 以在视图中呈现。

    类似:

    reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            // Got the download URL for 'users/me/profile.png'
    
            Glide.with(ViewScenesSG.this)
                    .load(uri.toString())
                    .into(imageView);
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle any errors
        }
    });
    

    【讨论】:

    • 好的,我看到了区别,但它仍然让我失败。
    • 我用新的错误更新了我的问题。它找不到对象。
    • 新的错误消息意味着reference 没有指向 Firebase 存储中的现有图像。您需要检查如何初始化 reference 并确保它所引用的图像存在。
    • Glide 可以通过 Firebase UI 中的插件了解 Firebase Storage。该插件需要安装才能正常工作。 firebase.google.com/docs/storage/android/…
    • 这是道格问题的一个单独部分。我决定选择一个线程并遵循它。我你想关注另一个话题,当然也可以,但最好在另一个答案中这样做。
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 2017-02-23
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多