You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中图片无法同步至Firebase Realtime Database求助

问题解决:Firebase图片上传与Realtime Database关联实现

你的问题核心在于图片上传是异步操作,当前代码中调用uploadImage()后立即执行数据库写入,但图片上传完成后没有将获取到的下载URL关联到对应的访客节点。以下是具体的修改方案:


步骤1:修改uploadImage方法,添加参数并获取图片下载URL

修改uploadImage方法,传入工单编号ticket,这样在图片上传成功后,可以精准定位到对应的访客节点写入图片URL:

private void uploadImage(final String ticket) {
    if (imageUri != null) {
        StorageReference reference = storage.getReference().child("images/" + UUID.randomUUID().toString());

        reference.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                if (task.isSuccessful()) {
                    // 获取图片下载URL并写入数据库
                    reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess(Uri uri) {
                            String imageUrl = uri.toString();
                            databaseReference.child("visitors").child(ticket).child("visitor image").setValue(imageUrl);
                            Toast.makeText(ActivityRequestVisit.this,"图片上传并关联成功", Toast.LENGTH_LONG).show();
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Toast.makeText(ActivityRequestVisit.this,"获取图片URL失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    });
                } else {
                    Toast.makeText(ActivityRequestVisit.this,task.getException().getMessage(), Toast.LENGTH_LONG).show();
                }
            }
        });
    } else {
        Toast.makeText(ActivityRequestVisit.this,"请先选择图片", Toast.LENGTH_LONG).show();
    }
}

步骤2:调整提交按钮的逻辑顺序

当前代码先调用uploadImage()再做表单验证,会导致无效上传。需先完成表单验证,确认工单编号唯一后,再执行数据库写入和图片上传:

修改提交按钮的点击事件如下:

SubmitRequestBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 获取输入数据
        final String name = VisitorName.getText().toString();
        final String ic = VisitorIC.getText().toString();
        final String phone = VisitorPhone.getText().toString();
        final String reason = VisitReason.getText().toString();
        final String dateV = VisitDate.getText().toString();
        final String timeV = VisitTime.getText().toString();
        final String ticket = VisitorTicket.getText().toString();

        // 表单验证
        if (TextUtils.isEmpty(name)) {
            Toast.makeText(ActivityRequestVisit.this,"请输入姓名", Toast.LENGTH_LONG).show();
            VisitorName.setError("姓名为必填项!");
            VisitorName.requestFocus();
        } else if (TextUtils.isEmpty(ic)) {
            Toast.makeText(ActivityRequestVisit.this,"请输入身份证号", Toast.LENGTH_LONG).show();
            VisitorIC.setError("身份证号为必填项!");
            VisitorIC.requestFocus();
        } else if (TextUtils.isEmpty(phone)) {
            Toast.makeText(ActivityRequestVisit.this,"请输入手机号", Toast.LENGTH_LONG).show();
            VisitorPhone.setError("手机号为必填项!");
            VisitorPhone.requestFocus();
        } else if (phone.length() != 10) {
            Toast.makeText(ActivityRequestVisit.this,"请重新输入手机号", Toast.LENGTH_LONG).show();
            VisitorPhone.setError("请输入有效的手机号!");
            VisitorPhone.requestFocus();
        } else if (TextUtils.isEmpty(reason)) {
            Toast.makeText(ActivityRequestVisit.this, "请输入来访事由", Toast.LENGTH_LONG).show();
            VisitReason.setError("来访事由为必填项!");
            VisitReason.requestFocus();
        } else if (TextUtils.isEmpty(dateV)) {
            Toast.makeText(ActivityRequestVisit.this, "请选择日期", Toast.LENGTH_LONG).show();
            VisitDate.setError("日期为必填项!");
            VisitDate.requestFocus();
        } else if (TextUtils.isEmpty(timeV)) {
            Toast.makeText(ActivityRequestVisit.this, "请选择时间", Toast.LENGTH_LONG).show();
            VisitTime.setError("时间为必填项!");
            VisitTime.requestFocus();
        }else if (TextUtils.isEmpty(ticket)) {
            Toast.makeText(ActivityRequestVisit.this, "请输入工单编号", Toast.LENGTH_LONG).show();
            VisitorTicket.setError("工单编号为必填项!");
            VisitorTicket.requestFocus();
        } else {
            // 检查工单编号唯一性
            databaseReference.child("visitors").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    if(snapshot.hasChild(ticket)){
                        Toast.makeText(ActivityRequestVisit.this,"该工单编号已存在,请重新生成", Toast.LENGTH_LONG).show();
                    }
                    else {
                        // 写入访客基本信息
                        databaseReference.child("visitors").child(ticket).child("visitor name").setValue(name);
                        databaseReference.child("visitors").child(ticket).child("visitor ic").setValue(ic);
                        databaseReference.child("visitors").child(ticket).child("visitor phone").setValue(phone);
                        databaseReference.child("visitors").child(ticket).child("visit reason").setValue(reason);
                        databaseReference.child("visitors").child(ticket).child("visit date").setValue(dateV);
                        databaseReference.child("visitors").child(ticket).child("visit time").setValue(timeV);

                        // 上传图片并关联URL
                        uploadImage(ticket);

                        Toast.makeText(ActivityRequestVisit.this,"提交请求成功", Toast.LENGTH_LONG).show();
                        finish();
                    }
                }
                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Toast.makeText(ActivityRequestVisit.this,"数据库操作失败: " + error.getMessage(), Toast.LENGTH_LONG).show();
                }
            });
        }
    }
});

关键说明

  1. 异步逻辑对齐:先完成表单验证和工单唯一性检查,写入基本信息后再触发图片上传,确保图片URL能关联到已创建的访客节点。
  2. 下载URL获取:图片上传成功后,通过getDownloadUrl()获取可公开访问的图片链接,写入Realtime Database的visitors/{ticket}/visitor image节点,达成你需要的关联效果。

内容的提问来源于stack exchange,提问作者The Ach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:01:11