Firebase Realtime Database:如何获取push()生成的数据?
Firebase数据存储与检索问题修复
问题根源分析
- 代码执行顺序错误:验证通过后直接调用
startActivity跳转页面,导致后续的setValue存储代码大概率没执行,这是你觉得只有首次数据能获取的核心原因之一。 - 数据结构设计不合理:用
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
相关产品推荐
相关产品推荐

