安卓Java新手求助:将Firebase Storage图片存入指定用户Firestore
解决Firebase Storage图片关联到Firestore用户的问题
你已经实现了图片上传到Storage,接下来只需要在上传成功后获取图片的下载URL,然后将这个URL和用户信息一起写入Firestore即可完成关联。以下是具体步骤和修改后的代码:
步骤说明
- 确保用户已通过Firebase Auth登录,这样才能获取唯一的用户ID来关联数据
- 上传图片成功后,调用
getDownloadUrl()获取图片的永久访问链接 - 在Firestore中创建集合(比如
userTestResults),将用户ID、图片URL、上传时间等信息存入文档
修改后的完整代码
public class BloodTestActivity extends AppCompatActivity { ImageView imageSelected; Button btn_uploadImage, btn_sendImage; Uri uri; StorageReference storageReference; ProgressDialog progressDialog; // 添加Firestore引用 FirebaseFirestore db; // 当前用户 FirebaseUser currentUser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_blood_test); imageSelected = findViewById(R.id.viewSelectedImage); btn_uploadImage = findViewById(R.id.btn_uploadImage); btn_sendImage = findViewById(R.id.btn_sendImage); // 初始化Firestore和当前用户 db = FirebaseFirestore.getInstance(); currentUser = FirebaseAuth.getInstance().getCurrentUser(); btn_uploadImage.setOnClickListener(v -> UploadImage()); btn_sendImage.setOnClickListener(v -> sendImage()); } private void sendImage() { // 先检查用户是否登录 if (currentUser == null) { Toast.makeText(this, "请先登录账号", Toast.LENGTH_SHORT).show(); return; } progressDialog = new ProgressDialog(this); progressDialog.setTitle("Sending test result..."); progressDialog.show(); SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.CANADA); Date now = new Date(); String fileName = format.format(now); storageReference = FirebaseStorage.getInstance().getReference("images/" + fileName); storageReference.putFile(uri) .addOnSuccessListener(taskSnapshot -> { // 上传成功后获取图片下载URL storageReference.getDownloadUrl().addOnSuccessListener(downloadUri -> { // 准备要存入Firestore的数据 Map<String, Object> testResult = new HashMap<>(); testResult.put("userId", currentUser.getUid()); testResult.put("imageUrl", downloadUri.toString()); testResult.put("uploadTime", new Timestamp(now)); testResult.put("fileName", fileName); // 写入Firestore,这里可以用用户ID作为文档ID,或者自动生成 db.collection("userTestResults") .add(testResult) .addOnSuccessListener(documentReference -> { imageSelected.setImageURI(null); Toast.makeText(BloodTestActivity.this, "上传并关联成功!", Toast.LENGTH_SHORT).show(); if (progressDialog.isShowing()) progressDialog.dismiss(); }) .addOnFailureListener(e -> { Toast.makeText(BloodTestActivity.this, "关联数据库失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); if (progressDialog.isShowing()) progressDialog.dismiss(); }); }).addOnFailureListener(e -> { Toast.makeText(BloodTestActivity.this, "获取图片链接失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); if (progressDialog.isShowing()) progressDialog.dismiss(); }); }) .addOnFailureListener(e -> { if (progressDialog.isShowing()) progressDialog.dismiss(); Toast.makeText(BloodTestActivity.this, "上传图片失败!", Toast.LENGTH_SHORT).show(); }); } private void UploadImage() { Dexter.withContext(this) .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new PermissionListener() { @Override public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, 101); } @Override public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) { Toast.makeText(BloodTestActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show(); } @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) { permissionToken.cancelPermissionRequest(); } }).check(); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 101 && resultCode == RESULT_OK){ uri = data.getData(); imageSelected.setImageURI(uri); } } }
关键修改点
- 添加Firestore和Auth引用:初始化
FirebaseFirestore和FirebaseUser,用于获取用户ID和操作数据库 - 用户登录校验:在上传前检查用户是否登录,避免无用户ID的情况
- 获取下载URL:图片上传成功后调用
getDownloadUrl()获取可访问的图片链接 - 写入Firestore:将用户ID、图片URL、上传时间等数据存入集合,完成图片与用户的关联
注意事项
- 确保你的项目已经添加了Firestore依赖,在
build.gradle中检查是否有:implementation 'com.google.firebase:firebase-firestore:24.11.0' implementation 'com.google.firebase:firebase-auth:22.3.1' - 可以根据需求调整Firestore的集合名称和存储的字段,比如添加检测类型、备注等信息
- 处理好各种失败回调,给用户明确的错误提示
内容的提问来源于stack exchange,提问作者Fonel1
相关产品推荐
相关产品推荐

