0

I want to get data from firebase without changing my database structure because I have two condition:

  1. When admin logins then he can see all employees data for the selected year or say year-wise.

  2. But when employees login then they should be able to see their individual data from all the years using employee code, which is a child also (blue tick in the picture).

Below is my database structure:

enter image description here

The child marked in red is unknown in case of employee's access and the blue tick denotes an employee who may be present in every year.

All I want is to achieve the 2nd condition. But I am unable to get the data. Here is my code:

private void retrieveData() {

    final String shift = kvName.getText().toString();
    final String employeeCode = empCode.getText().toString();

    dbRef.child("Apar").child(shift);

    dbRef.orderByChild(employeeCode).equalTo(employeeCode).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot datas1 : dataSnapshot.getChildren()) {

                for (DataSnapshot datas2 : datas1.getChildren()) {
                   // String aparGrading= datas2.getKey();  //unable to figure out how to get
                 //   Toast.makeText(Apar.this, aparGrading, Toast.LENGTH_LONG).show();
                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • The Firebase Realtime Database and Cloud Firestore are two separate databases. Please only mark your question with the relevant tag, not with both. – Frank van Puffelen Mar 08 '22 at 20:48

2 Answers2

1

Your current data structure makes it easy to find the information for all employees for a specific year. It does however not make it easy to find the information for a specific employee across all years.

To do the latter, you have two options:

  • Check each year for the presence of a node for that employee ID.
  • Add an additional data structure that maps from each employee ID to the years for which they have data, and then load each year's data for that employee individually

For more on this, also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • What if we modify the data structure by interchanging those two node? I mean Just after Shift Child we set the child as Emp Code and inside that all the years child would be there. This way it will be easier for employees to access their node and get every years data. In that case how an admin can loop through all the child (emp code) and check if it contains a child (specific year) so that he can get each employees data for a specific year. – s4surajverma Mar 09 '22 at 02:43
  • Thank you Mr. Frank. Your answers which you have linked above on this topic really helped me understand the things. And after spending some times finally I achieved what I wanted without changing my database structure. – s4surajverma Mar 09 '22 at 09:03
0

After reading the various answers on this topic linked above by Mr. @Frank van Puffelen and spending some times over it, the problem is finally solved now without changing my database structure. Below is screenshot of the result which I wanted:

enter image description here

Here is my modified and working code :

private void retrieveData() {

    final String shift = kvName.getText().toString();
    final String employeeCode = empCode.getText().toString();

    final DatabaseReference aparRef = dbRef.child("Apar").child(shift);

    aparRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            list = new ArrayList<>();

            if (dataSnapshot.exists()) {

                for (DataSnapshot dataS1 : dataSnapshot.getChildren()) {

                    if (dataS1.hasChild(employeeCode)) {


                        AparData aparData = dataS1.child(employeeCode).getValue(AparData.class);
                        list.add(aparData);

                        rvAPAR.setHasFixedSize(true);
                        rvAPAR.setLayoutManager(new LinearLayoutManager(Apar.this));
                        rvAPAR.setItemAnimator(new DefaultItemAnimator());
                        aparAdapter = new AparAdapter(Apar.this, list);
                        rvAPAR.setAdapter(aparAdapter);

                    } else {
                        Toast.makeText(Apar.this, "No Data Found!!", Toast.LENGTH_SHORT).show();
                    }

                }
            } else {
                Toast.makeText(Apar.this, "Not Data Found!!", Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

}
  • 1
    This solution loads the entire `Apar` node, and then checks where the user exists in it client side. While this may work, it won't scale when as you add more users to the app since you're loading the data for all users instead of loading the data for just `employeeCode`. – Frank van Puffelen Mar 09 '22 at 14:51
  • Actually I am a newbie to firebase so not getting the exact thing that how should I proceed with this situation. – s4surajverma Mar 09 '22 at 15:44