0

I'm still new at this. Used a push() when storing data, but now am having trouble retrieving it, I can only retrieve the information that was stored the first time before using the push(). Here is the code I used to store the information.

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

        //get all the values
        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;
        }
        else {
            Toast.makeText(getApplicationContext(),"registered",Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(MainActivity.this,fbase.class);
            startActivity(intent);
        }

        Userhelperclass helperclass = new Userhelperclass(firstName,lastName,idnumber,dateofBirth,email,phoneNumber,nextofKin,nextofKinNumber,password);
        reference.child(idnumber).push().setValue(helperclass);
    }
});

This is the code that am using to retrieve information. So this only gets the information that has been stored for the first time.

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");
    Query checkUser = reference.orderByChild("idnumber").equalTo(userEnteredIdNumber);

    checkUser.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {

            if (snapshot.exists()){
                idnum.setError(null);
                idnum.setErrorEnabled(false);

                String passwordFromDb = snapshot.child(userEnteredIdNumber).child("password").getValue(String.class);
                String firstnameFromDb = snapshot.child(userEnteredIdNumber).child("firstName").getValue(String.class);

                idnum.setError(null);
                idnum.setErrorEnabled(false);


                if (passwordFromDb.equals(userEnteredPassword) && firstnameFromDb.equals(userEnteredFirstName)){

                    String lastnamesFromDb = snapshot.child(userEnteredIdNumber).child("lastName").getValue(String.class);
                    String idnumbersFromDb = snapshot.child(userEnteredIdNumber).child("idnumber").getValue(String.class);
                    String birthsFromDb = snapshot.child(userEnteredIdNumber).child("dateofBirth").getValue(String.class);
                    String mailsFromDb = snapshot.child(userEnteredIdNumber).child("email").getValue(String.class);
                    String contactsFromDb = snapshot.child(userEnteredIdNumber).child("phoneNumber").getValue(String.class);
                    String kinsFromDb = snapshot.child(userEnteredIdNumber).child("nextofKin").getValue(String.class);
                    String kinsnumberFromDb = snapshot.child(userEnteredIdNumber).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) {

        }
    });

}

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

1 Answers1

0

If I read your code correctly you have this data structure:

Users: {
  $idnumber: {
    $pushkey: {
      idnumber: $idnumber
    }
  }
}

There is no way to query for the idnumber property across all users as your code is trying to do, as queries on the Realtime Database can only contain one level of unknown keys and you have two ($idnumber and $pushkey). Also see: Firebase Query Double Nested

But since you also have $idnumber as the key under Users, you can load that node with a query and then loop over its $pushkey child nodes with:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
Query theUser = reference.child(userEnteredIdNumber);

theUser.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
        for (DataSnapshot pushSnapshot: snapshot.getChildren()) { //  Loop over push keys
            String passwordFromDb = pushSnapshot.child("password").getValue(String.class);
            ...
         }
    }


    @Override
    public void onCancelled(@NonNull @NotNull DatabaseError error) {
        throw error.toException(); //  Never ignore errors
    }
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hi Frank, what comes after the loop? I have tried the setText and also the if statement but it keeps crashing. – Allan Otieno Jan 03 '23 at 09:45
  • Let's take it one step at a time: did the explanation I gave in my answer make sense? And did you set a breakpoint, run in a debugger, and check that `passwordFromDb` now gets the correct value? If so, there might still be other problems in your code, for which I'd recommend posting a new question with its own [minimal repro](http://stackoverflow.com/help/mcve). – Frank van Puffelen Jan 03 '23 at 14:12
  • To be honest, I do not understand. Like I said am still new at this. I tried using the getEditText().setText immediately below it. String passwordFromDb = pushSnapshot.child("password").getValue(String.class); pass_word.getEditText().setText(passwordFromDb); – Allan Otieno Jan 03 '23 at 21:53
  • Instead of doing that in the UI, how about setting a breakpoint on that line and running in a debugger? https://developer.android.com/codelabs/basic-android-kotlin-compose-intro-debugger – Frank van Puffelen Jan 03 '23 at 22:23
  • It's giving me the details of the push function. I was asking ho do I display that information using the UI? – Allan Otieno Jan 04 '23 at 03:12
  • @AllanOtieno I'm really trying to help here. Did you set a breakpoint, run in the debugger, and check what value it gets for `passwordFromDb`? If so, what is the result? "giving me the details of the push function" makes little sense in that context. You should be able to see the value of the variable, and that either matches the value from the database (in which case my code solves that problem) or it doesn't (in which case we need to continue searching why it doesn't laod the correct data). – Frank van Puffelen Jan 04 '23 at 05:04
  • Yes, I set a breakpoint at passwordFromDb and the variable matched the value from the database.Your code worked. Thank you. But one last question, why does it show on the debugger but not on the UI? – Allan Otieno Jan 04 '23 at 08:53