Android应用从Firebase Storage、Realtime Database加载图片不显示问题
问题根因
你当前写法错误是因为新版Firebase Storage SDK中,getDownloadUrl()返回的是异步Task<Uri>对象,而非直接返回下载链接。你直接调用toString()存储的是Task实例的描述信息,并非可访问的图片地址,所以存入数据库的url无效,无法加载图片。你手动替换为Storage真实访问链接可正常加载,也验证了这个问题。
修改方案
你需要监听getDownloadUrl()的异步返回结果,拿到真实Uri后再写入Realtime Database,修改代码如下:
需替换的核心代码段
将原来的错误代码:
Upload upload = new Upload(productName.getText().toString().trim(), productDesc.getText().toString().trim(), taskSnapshot.getMetadata(). getReference().getDownloadUrl().toString()); String uploadId = mDatabaseRef.push().getKey(); mDatabaseRef.child(uploadId).setValue(upload);
替换为:
// 异步获取真实下载地址 taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { String realImageUrl = uri.toString(); Upload upload = new Upload(productName.getText().toString().trim(), productDesc.getText().toString().trim(), realImageUrl); String uploadId = mDatabaseRef.push().getKey(); mDatabaseRef.child(uploadId).setValue(upload); } });
完整修改后的uploadFile方法
private void uploadFile() { if(mImageUri != null){ StorageReference fileReference = mStorageRef.child(System.currentTimeMillis() + "." + getFileExtension(mImageUri)); mUploadTask = fileReference.putFile(mImageUri) .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { uploadProgress.setProgress(0); } }, 1000); Toast.makeText(AddItemForSale.this, "Upload successful", Toast.LENGTH_LONG).show(); // 异步获取下载链接后再写入数据库 taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { String realImageUrl = uri.toString(); Upload upload = new Upload(productName.getText().toString().trim(), productDesc.getText().toString().trim(), realImageUrl); String uploadId = mDatabaseRef.push().getKey(); mDatabaseRef.child(uploadId).setValue(upload); } }); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(AddItemForSale.this, e.getMessage(), Toast.LENGTH_SHORT).show(); } }) .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(@NonNull UploadTask.TaskSnapshot snapshot) { double progress = (100.0 * snapshot.getBytesTransferred() / snapshot.getTotalByteCount()); uploadProgress.setProgress((int) progress); } }); }else { Toast.makeText(this, "No file selected", Toast.LENGTH_SHORT).show(); } }
如果你的项目支持Java 8+ lambda表达式,可自行简化匿名内部类的写法。
内容的提问来源于stack exchange,提问作者Ranko Koturic
相关产品推荐
相关产品推荐

