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

Firebase数据库未按Model类存储用户信息问题排查求助

Firebase PDF上传节点缺失用户名和学号的问题排查

问题背景

开发了一个上传PDF到Firebase的Fragment,期望在resume-uploads节点存储文件名、文件URL、上传用户名及用户学号,但目前该节点仅存储文件名和URL,用户名与学号未被正确写入。

错误原因分析

1. 异步数据读取导致赋值延迟

在uploadPDFFile方法中,调用setUsernameAndEnrollment()后立刻创建UploadResumeFile对象并写入数据库,但addValueEventListener是异步操作——此时username和enrollment还未从数据库获取到实际值,依然为null,因此无法被写入节点。

2. 模型类Getter方法命名不符合Firebase序列化规则

UploadResumeFile类中,username字段对应的Getter方法是getUser_name(),Firebase序列化时会根据Getter方法名生成字段名(即user_name),但你期望存储的字段是username,两者不匹配,导致即使有值也无法正确映射到目标字段。

修复方案

方案一:修正异步数据读取逻辑

将创建UploadResumeFile并写入数据库的逻辑,放到数据库读取回调的onDataChange方法中,确保获取到用户数据后再执行写入操作;同时使用addListenerForSingleValueEvent替代addValueEventListener,因为只需要获取一次用户数据,避免不必要的持续监听。

方案二:修正模型类Getter/Setter方法命名

将UploadResumeFile中username字段的Getter方法改为getUsername(),Setter方法改为setUsername(),保证与字段名一致,符合Firebase的序列化规则。

代码修改示例

1. 修改uploadPDFFile方法的异步逻辑

private void uploadPDFFile(Uri data) {
    final ProgressDialog progressDialog = new ProgressDialog(getActivity());
    progressDialog.setTitle("uploading...");
    progressDialog.show();
    StorageReference reference = storageReference.child("resumeUploads/" + System.currentTimeMillis() + ".pdf");
    reference.putFile(data).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
            while (!uriTask.isComplete()) ;
            Uri url = uriTask.getResult();

            // 直接在回调中获取用户数据,确保异步完成后再写入数据库
            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    UserDataStore userDataStore = snapshot.getValue(UserDataStore.class);
                    if (user != null && userDataStore != null) {
                        String username = userDataStore.getName();
                        String enrollment = userDataStore.getEnrollment();
                        // 创建上传对象并写入数据库
                        UploadResumeFile uploadResumeFile = new UploadResumeFile(
                                editPDFName.getText().toString(),
                                url.toString(),
                                username,
                                enrollment
                        );
                        if (FirebaseAuth.getInstance().getCurrentUser() != null) {
                            databaseReference.child(databaseReference.push().getKey()).setValue(uploadResumeFile);
                        }
                        Toast.makeText(getActivity(), "File Uploaded Successfully", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(getActivity(), "Failed to retrieve user data", Toast.LENGTH_SHORT).show();
                    }
                    progressDialog.dismiss();
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Toast.makeText(getActivity(), "Database error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
                    progressDialog.dismiss();
                }
            });
        }
    }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onProgress(@NonNull UploadTask.TaskSnapshot snapshot) {
            progressDialog.setMessage("Uploading...");
        }
    });
}

2. 修正UploadResumeFile模型类的方法命名

public class UploadResumeFile {
    public String name;
    public String url;
    public String username;
    public String enrollment;

    public UploadResumeFile() {}

    public UploadResumeFile(String name, String url, String username, String enrollment) {
        this.name = name;
        this.url = url;
        this.username = username;
        this.enrollment = enrollment;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    // 修正Getter/Setter方法名,与字段名保持一致
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEnrollment() {
        return enrollment;
    }

    public void setEnrollment(String enrollment) {
        this.enrollment = enrollment;
    }
}

额外优化建议

  • 移除原有的setUsernameAndEnrollment()方法,避免冗余逻辑。
  • 增加数据库读取失败的错误提示,提升用户体验。
  • 可考虑在登录时将用户数据缓存到本地,避免每次上传都重复读取数据库,提升操作效率。

内容的提问来源于stack exchange,提问作者Anushka yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:39:32