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

Firebase Realtime Database:如何获取push()生成的数据?

Firebase数据存储与检索问题修复

问题根源分析

  1. 代码执行顺序错误:验证通过后直接调用startActivity跳转页面,导致后续的setValue存储代码大概率没执行,这是你觉得只有首次数据能获取的核心原因之一。
  2. 数据结构设计不合理:用reference.child(idnumber).push().setValue(...)会让用户数据嵌套在Users/{idnumber}/{随机pushID}路径下,但检索代码直接去Users/{idnumber}下取字段,自然拿不到pushID里的数据。而且身份证号是唯一标识,完全没必要用push()生成额外ID。

修复后的存储代码

把数据存储逻辑移到跳转前,同时去掉多余的push():

regBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        rootnode = FirebaseDatabase.getInstance();
        reference = rootnode.getReference("Users");

        // 获取输入值
        String firstName = fname.getEditText().getText().toString();
        String lastName = lname.getEditText().getText().toString();
        String idnumber = idnum.getEditText().getText().toString();
        String dateofBirth = dateob.getEditText().getText().toString();
        String email = e_mail.getEditText().getText().toString();
        String phoneNumber = pnum.getEditText().getText().toString();
        String nextofKin = kin.getEditText().getText().toString();
        String nextofKinNumber = nkin.getEditText().getText().toString();
        String password = pass_word.getEditText().getText().toString();

        if (!validateFirstName() | !validateLastName() | !validateIdNumber() | !validateDateofBirth() | !validateEmaiL() | !validatePhoneNumber() | !validateNextOFKin() | !validateNextOfKinContact() | !validatePassWord()){
            return;
        }
        
        // 先存储数据,再执行跳转
        Userhelperclass helperclass = new Userhelperclass(firstName,lastName,idnumber,dateofBirth,email,phoneNumber,nextofKin,nextofKinNumber,password);
        reference.child(idnumber).setValue(helperclass);
        
        Toast.makeText(getApplicationContext(),"registered",Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(MainActivity.this,fbase.class);
        startActivity(intent);
    }
});

修复后的检索代码

现在数据直接存在Users/{idnumber}下,不需要用orderByChild查询,直接访问对应节点即可,效率更高:

private void isUser() {
    String userEnteredIdNumber = idnum.getEditText().getText().toString().trim();
    String userEnteredPassword = pass_word.getEditText().getText().toString().trim();
    String userEnteredFirstName = fname.getEditText().getText().toString().trim();

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
    // 直接访问用户ID对应的节点
    reference.child(userEnteredIdNumber).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
            if (snapshot.exists()){
                idnum.setError(null);
                idnum.setErrorEnabled(false);

                // 直接从当前节点读取字段
                String passwordFromDb = snapshot.child("password").getValue(String.class);
                String firstnameFromDb = snapshot.child("firstName").getValue(String.class);

                if (passwordFromDb.equals(userEnteredPassword) && firstnameFromDb.equals(userEnteredFirstName)){
                    // 读取其他用户信息
                    String lastnamesFromDb = snapshot.child("lastName").getValue(String.class);
                    String idnumbersFromDb = snapshot.child("idnumber").getValue(String.class);
                    String birthsFromDb = snapshot.child("dateofBirth").getValue(String.class);
                    String mailsFromDb = snapshot.child("email").getValue(String.class);
                    String contactsFromDb = snapshot.child("phoneNumber").getValue(String.class);
                    String kinsFromDb = snapshot.child("nextofKin").getValue(String.class);
                    String kinsnumberFromDb = snapshot.child("nextofKinNumber").getValue(String.class);

                    // 将数据填充到输入框
                    fname.getEditText().setText(firstnameFromDb);
                    lname.getEditText().setText(lastnamesFromDb);
                    idnum.getEditText().setText(idnumbersFromDb);
                    dateob.getEditText().setText(birthsFromDb);
                    e_mail.getEditText().setText(mailsFromDb);
                    pnum.getEditText().setText(contactsFromDb);
                    kin.getEditText().setText(kinsFromDb);
                    nkin.getEditText().setText(kinsnumberFromDb);
                    pass_word.getEditText().setText(passwordFromDb);
                } else if(!passwordFromDb.equals(userEnteredPassword)){
                    pass_word.setError("wrong password");
                } else {
                    fname.setError("Wrong name");
                }
            } else {
                idnum.setError("No such user exists");
                idnum.requestFocus();
            }
        }

        @Override
        public void onCancelled(@NonNull @NotNull DatabaseError error) {}
    });
}

特殊场景补充(若需保留push())

如果确实需要用push()(比如同一个身份证号对应多条记录),检索时需要遍历snapshot.getChildren()获取每个pushID下的数据:

checkUser.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        if (snapshot.exists()){
            for(DataSnapshot child : snapshot.getChildren()){
                String passwordFromDb = child.child("password").getValue(String.class);
                // 其他字段读取逻辑同理
            }
        }
    }
});

但针对你的单用户单记录场景,用身份证号作为节点键是更合理的设计。

内容的提问来源于stack exchange,提问作者Allan Otieno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:10:28