调用Firebase的.getDownloadUrl()无法获取图片URL,数据库存zzu对象而非链接
问题排查与解决方案
问题根源
你遇到的存储值异常是因为getDownloadUrl()方法返回的是异步Task对象,不是直接的URL字符串,你直接对它调用toString()获取到的是Task对象的内存标识,也就是你现在存到数据库里的com.google.android.gms.tasks.zzu@e2b2b97这类内容,不是真实的图片访问链接。
修正方案
你需要在getDownloadUrl()的成功回调里拿到真实的URL,再写入Firebase Realtime Database即可,同时你现有代码里存在重复调用push()生成两次key的冗余问题,也可以一起修正。
修正后的核心代码(替换你现有submit_restaurant()方法即可):
private void submit_restaurant() { if(restaurantImgUri !=null){ StorageReference fileReference = storageref.child(System.currentTimeMillis() + "." + getFileExtension(restaurantImgUri)); fileReference.putFile(restaurantImgUri) .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { progressBar.setProgress(0); } },3000); progressBar.setVisibility(View.INVISIBLE); Toast.makeText(addrestaurant.this, "图片上传成功,正在获取访问链接", Toast.LENGTH_SHORT).show(); // 异步获取图片下载链接 taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { // 此处拿到真实的图片访问链接 String realImageUrl = uri.toString(); // 仅生成一次数据库key即可,无需重复调用push() String uploadId = databaseref.push().getKey(); places restaurant = new places( restaurant_name.getText().toString().trim(), restaurant_desc.getText().toString().trim(), realImageUrl, 5, restaurant_add.getText().toString().trim() ); databaseref.child(uploadId).setValue(restaurant); Toast.makeText(addrestaurant.this, "餐厅信息提交成功", Toast.LENGTH_SHORT).show(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(addrestaurant.this, "获取图片链接失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } }); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(addrestaurant.this, "图片上传失败:" + e.toString(), 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()); progressBar.setVisibility(View.VISIBLE); progressBar.setProgress((int) progress); } }); }else{ Toast.makeText(this, "未选择任何图片文件", Toast.LENGTH_SHORT).show(); } }
注意事项
- Firebase所有返回Task的方法都是异步操作,必须在对应的成功回调里处理后续逻辑,不能直接同步获取返回值
- 确认你的
places实体类构造方法的参数顺序和传入的参数一致,避免数据库字段写入错位
内容的提问来源于stack exchange,提问作者Zabava Mihai
相关产品推荐
相关产品推荐

