从 Firebase 存储中检索图像
Retrieving image from Firebase Storage
我知道这是一个讨论过的话题,但在我找到的所有其他解决方案都没有解决我的问题之后,我就来了。我在 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()
方法 => 构建错误。我相信它已被删除。
我试过的第二个版本是这个(在另一个问题中找到):
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();
}
});
但每次都在 Failure 侦听器上。因此,我的 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[=13=]0(com.google.firebase:firebase-storage@@19.1.1:36)
at com.google.firebase.storage.StreamDownloadTask.call(com.google.firebase:firebase-storage@@19.1.1:167)
at com.google.firebase.storage.StreamDownloadTask.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.access0(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(com.google.firebase:firebase-storage@@19.1.1:1072)
at com.google.firebase.storage.StorageTask$$Lambda.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)
我不确定你的第二个代码片段出了什么问题,但在第一个代码片段中你似乎将 StorageReference
传递给了 Glide。由于 Glide 对 Firebase 存储一无所知,因此无法正常工作。
相反,您应该从 Firebase Storage 下载 URL,这是一个常规的 HTTPS URL,提供对数据的 public 访问,并将其传递给 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
}
});
我发现了以下 solution(如之前评论中所建议):
使用 Firebase UI 插件和 Gilde,我添加了以下依赖项:
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 必须将 尺寸 设置为特定值,而不是使用 wrap_content
或 match_parent
(至少对于高度我的情况),否则它将显示为一个小图标。这也可能取决于图像之前在存储中的保存方式。
希望这对其他人也有帮助!
我知道这是一个讨论过的话题,但在我找到的所有其他解决方案都没有解决我的问题之后,我就来了。我在 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()
方法 => 构建错误。我相信它已被删除。
我试过的第二个版本是这个(在另一个问题
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();
}
});
但每次都在 Failure 侦听器上。因此,我的 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[=13=]0(com.google.firebase:firebase-storage@@19.1.1:36)
at com.google.firebase.storage.StreamDownloadTask.call(com.google.firebase:firebase-storage@@19.1.1:167)
at com.google.firebase.storage.StreamDownloadTask.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.access0(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(com.google.firebase:firebase-storage@@19.1.1:1072)
at com.google.firebase.storage.StorageTask$$Lambda.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)
我不确定你的第二个代码片段出了什么问题,但在第一个代码片段中你似乎将 StorageReference
传递给了 Glide。由于 Glide 对 Firebase 存储一无所知,因此无法正常工作。
相反,您应该从 Firebase Storage 下载 URL,这是一个常规的 HTTPS URL,提供对数据的 public 访问,并将其传递给 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
}
});
我发现了以下 solution(如之前评论中所建议):
使用 Firebase UI 插件和 Gilde,我添加了以下依赖项:
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 必须将 尺寸 设置为特定值,而不是使用 wrap_content
或 match_parent
(至少对于高度我的情况),否则它将显示为一个小图标。这也可能取决于图像之前在存储中的保存方式。
希望这对其他人也有帮助!