java - 如何从 firebase 存储中获取 imageUrl 以存储在 firebase 实时数据库中?
问题描述
基本上我创建了一个名为“俱乐部”的课程。我成功地将一个新俱乐部保存到 firebase 实时数据库,没有任何实际问题,直到我想将 Firebase 存储中的 imageURL(称为 clubImage)添加到我的俱乐部类。
我可以使用以下代码成功地将我的图像上传到 Firebase 存储。
private void uploadImage() {
//upload selected image to database
//code from https://code.tutsplus.com/tutorials/image-upload-to-firebase-in-android-application--cms-29934
if(filePath != null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
final StorageReference ref = storageReference.child("images/"+ UUID.randomUUID().toString());
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(AddClubActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(AddClubActivity.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+"%");
}
});
}
}
这一切都很好。但是,在同样的方法中,我也有这段代码,我尝试在其中获取上传图像的下载 URL。
ref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
Uri downloadUrl = uri;
clubImage = downloadUrl.toString();
}
});
我知道为同一件事设置两个 OnSuccessListener 效率很低,我只是不确定如何同时上传图像和获取 downloadUrl。无论如何,这不起作用,我的新俱乐部在没有 clubImage 字段的情况下保存。我收到错误:E/StorageException:StorageException 已发生。对象在该位置不存在。
有谁知道如何解决这一问题?谢谢。
解决方案
我知道为同一件事设置两个 OnSuccessListener 效率低下
您有两个要尝试完成的任务:
- 上传一个文件
- 获取该文件的下载 URL
由于这是两个独立的任务,因此您需要两个OnSuccessListeners
. 这并没有什么低效的地方,任务也不尽相同。
上传后获取下载 URL的 Firebase 文档准确地展示了如何连续完成这两个任务:
final StorageReference ref = storageRef.child("images/mountains.jpg"); uploadTask = ref.putFile(file); Task<Uri> urlTask = uploadTask.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(); } // Continue with the task to get the download URL return ref.getDownloadUrl(); } }).addOnCompleteListener(new OnCompleteListener<Uri>() { @Override public void onComplete(@NonNull Task<Uri> task) { if (task.isSuccessful()) { Uri downloadUri = task.getResult(); } else { // Handle failures // ... } } });
您会注意到,此代码首先完成uploadTask
(上传文件),然后才开始一个新任务以获取下载 URL。按此顺序执行任务可防止您收到“对象在该位置不存在”错误消息。
推荐阅读
- javascript - 带有“Field.subField”的 Firebase where 子句没有匹配的文档
- c# - 将 ItemsSource 与 ReactiveUI 绑定时,ComboBox 必须定义 ComboBox.ItemTemplate
- r - 如何从带有 xts 的列表中按日期查找值
- c# - C# ApplicationBase 返回值字母大小写与磁盘上的文件夹路径不同
- powershell - Powershell:基于动态菜单的程序来复制文件
- json - 使用 SearchDelegate Flutter 从 JSON 对象列表中搜索
- swift - 被有效释放的闭包引用的指针会发生什么?
- python-3.x - 尝试遍历以下输出 python
- r - 有没有更简单的方法来绘制相对频率直方图
- line - 这个 LAN 单线图中的 TPB-2 和 IC 是什么意思?