如何为图片设置下载URL并存入Firestore数据库与实时数据库
问题根因
你获取下载地址时调用了错误的Storage引用:全局声明的storageReference指向的是Profile Pictures整个文件夹,不是你刚刚上传成功的单张头像文件的引用,无法获取到对应文件的有效下载URL,导致后续数据库写入操作没有有效可存的内容。
修复方案
将上传成功回调里的storageReference.getDownloadUrl()替换为本次上传使用的具体文件引用reference.getDownloadUrl()即可,同时补充了必要的异常判断避免崩溃,修正后的核心代码如下:
update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 补充未选图拦截逻辑,避免空指针崩溃 if (photoUri == null) { Toast.makeText(getContext(), "请先选择要上传的头像", Toast.LENGTH_SHORT).show(); return; } progressDialog.show(); // 本次上传的具体头像文件引用 StorageReference reference = storage.getReference().child("Profile Pictures") .child(FirebaseAuth.getInstance().getUid()); reference.putFile(photoUri) .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { // 用本次上传的文件引用获取下载URL,替换原有的全局storageReference reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { imageUrl = uri.toString(); updateUserProfileToFirestore(); updateUserProfileToDataBase(); } }).addOnFailureListener(e -> { progressDialog.dismiss(); Toast.makeText(getContext(), "获取图片地址失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); }); } }) .addOnFailureListener(e -> { progressDialog.dismiss(); Toast.makeText(getContext(), "图片上传失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); }) .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(@NonNull @NotNull UploadTask.TaskSnapshot snapshot) { long totalSi = snapshot.getTotalByteCount(); long transferS = snapshot.getBytesTransferred(); long totalSize = (totalSi / 1024); long transferSize = transferS / 1024; progressDialog.setMessage("已上传 " + ((int) transferSize) + "KB / " + ((int) totalSize) + "KB"); } }); } });
可选优化建议
- 删除代码中重复的
FirebaseAuth初始化语句,避免冗余操作 - 在
onActivityResult拿到选中的图片Uri后,直接赋值给头像控件显示,给用户即时操作反馈 - 若修改后仍写入失败,先检查Firestore、实时数据库的安全规则,是否允许已登录用户修改自己对应用户ID节点的字段权限。
内容的提问来源于stack exchange,提问作者Angel
相关产品推荐
相关产品推荐

