1

We are creating an app where the teacher can create his class register, and it should look like that: Teacher creates his profile, after that there is an activity with RecyclerView that displays students names. Below RecyclerView there is TextView that says "Student! create your own profile" (ofcourse after clicking it, there is an activity for creating students profile). Student can create his profile only by using the same device as teacher while he was creating Teachers Profile. Ok, that looks nice and so far we have it all done, but here comes our question. What is the best behaviour to store users data in this case? Should we structure our data this way?

{
  "Teachers" : {
    "USYSacnOjDR5EAPwljZMHtggN9I2" : {
      "teachername" : {
        "teachername" : "Janis"
      },
        "students" : {
          "0xgMzfOLLwQ2KWF7aKhH5ZIbQnx2":{
            "studentname": "Pavel"

         }
      }
    }
  },

So, this looks like veeery badly structured data, we know it, but like we said before, We need to display in RecyclerView the names of this specific teacher students that are other FirebaseAuth users and had their own datas like grades Every opinion or critique is appreciated.

@Edit here is how i retrieve data :) reference=FirebaseDatabase.getInstance().getReference("teachers").child(teacherkey).child("users");

 reference.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                User user = dataSnapshot.child("name").getValue(User.class);
                result.add(user);
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                User user = dataSnapshot.child("name").getValue(User.class);
                result.remove(user);
                adapter.notifyDataSetChanged();
            }
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
jj.badweyn
  • 123
  • 3
  • 10
  • 1
    Please add picture of how you want the data to be displayed. – Alex Mamo May 17 '18 at 13:21
  • 1
    What do you mean, u want firebase screenshot or paint artwork? :) Maybe i can describe it simplier, i do believe its kinda complicated, so: One device, one teacher, 5 students. Teacher creates account, then students can create their own. In RecyclerView i want to display only these 5 students name :) – jj.badweyn May 17 '18 at 13:30

1 Answers1

2

According to your comment, a possible database structure can be this:

Firebase-root
   |
   --- teachers
   |     |
   |     --- teacherIdOne
   |     |      |
   |     |      --- "teacherName" : "Teacher Name One"
   |     |      |
   |     |      --- students:
   |     |             |
   |     |             --- studentIdOne: "Student Name One"
   |     |             |
   |     |             --- studentIdTwo: "Student Name Two"
   |     |
   |     --- teacherIdTwo
   |            |
   |            --- "teacherName" : "Teacher Name Two"
   |            |
   |            --- students:
   |                   |
   |                   --- studentIdThree: "Student Name Three"
   |                   |
   |                   --- studentIdFour: "Student Name Four"
   |
   --- students
         |
         --- studentIdOne
         |      |
         |      --- "studentName" : "Student Name One"
         |
         --- studentIdTwo
         |      |
         |      --- "studentName" : "Student Name Two"
         |
         --- studentIdThree
         |      |
         |      --- "studentName" : "Student Name Three"
         |
         --- studentIdFour
         |      |
         |      --- "studentName" : "Student Name Four"
         |
         --- studentIdFive
                |
                --- "studentName" : "Student Name Five"

And to display all 5 students name, please use the following code:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference studentsRef = rootRef.child("students");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String studentName = ds.child("studentName").getValue(String.class);
            Log.d("TAG", studentName);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
studentsRef.addListenerForSingleValueEvent(valueEventListener);

Te output will be:

Student Name One
Student Name Two
Student Name Three
Student Name Four
Student Name Five

If you are interested in displaying those names into a RecyclerView, this is how you can retrieve data from a Firebase Realtime database and display it in a RecyclerView using FirebaseRecyclerAdapter.

If you want to display the student of a particular teacher, please use the following code:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference studentsRef = rootRef.child(teachers).child(teacherId).child("students");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String studentName = ds.getValue();
            Log.d("TAG", studentName);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
studentsRef.addListenerForSingleValueEvent(valueEventListener);

In which the teacherId is the id of the teacher you want to display its students. If the id of the teacher is for example teacherIdOne, the output will be:

Student Name One
Student Name Two
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • :D Well i described my problem very bad i guess. Ok so to be clear, an app was displaying student names, recylcerview was working well and everythink was nice. I was asking what should i do if let say, there will be 2nd or 55th teacher with his class and new student names :) U got me now? I need to link somehow student accounts to teachers account :) – jj.badweyn May 17 '18 at 13:49
  • Plase see my updated answer in which you can see all the students that corrspond to a specific teacher. If want, you can use instead of the `boolean` true the name of the student. – Alex Mamo May 17 '18 at 13:53
  • Allright, but i still retrieve every student name not only these who are signed to teacher. I structured the data like you said, with true `boolean` – jj.badweyn May 17 '18 at 14:33
  • Please see again my updated answer. Does it work now? – Alex Mamo May 17 '18 at 15:07
  • Actually i retrieve data by `childEventListener` i edited the question and added my code, app crashs because `RecyclerView` gets null value, i cant figure it out :D probably too much time without break ;) @edit It retrieves 'studentkey` and `value: true` – jj.badweyn May 17 '18 at 15:26
  • Inside `onChildAdded` and `onChildChanged` remove this `.child("name")`. It is ok now? – Alex Mamo May 17 '18 at 15:36
  • No no, thats not the problem for sure, but i checked it and it crash. While im debbuging it i see that when it comes to `User user = dataSnapshot.child("name").getValue(User.class);` debbuger shows that the key is `uid` but `value` is `true` i guess it should work as a kind of bridge and in `value` i should see all of user data childs with values, just the same way like i see it when im trying to normally retrieve data from user – jj.badweyn May 17 '18 at 15:41
  • If you want to display using the model class, use this: `User user = dataSnapshot.getValue(User.class);`, otherwise this: `String studentName = ds.getValue();`, right? – Alex Mamo May 17 '18 at 15:46
  • Please see again my updated answer regarding the database structure. I have changed the boolean with the student names, see? – Alex Mamo May 17 '18 at 15:47
  • Oh ok now i understand, i guess we are talking about 2 different things. You are retrieving username straight from `teachers-teachersid-students-studentsid-studentsname`. Well the thing is that i need to retrieve it from `students-studentsid-studentname` root, because in studenstid i have more details like surname, thats why i think i should use `boolean` true – jj.badweyn May 17 '18 at 15:57
  • In this case, just use: `User user = dataSnapshot.getValue(User.class);` – Alex Mamo May 17 '18 at 15:59
  • When i use `User user = dataSnapshot.getValue(User.class);` i get `Can't convert object of type java.lang.Boolean ` and when i use `User user = dataSnapshot.child("name").getValue(User.class);` i get NPE – jj.badweyn May 17 '18 at 16:06
  • I understand now what you are saying. Try to understand the concept. Using my code, you can get only the name of the students because here: `.child(teachers).child(teacherId).child("students")` there are only student names, please see again the database structure. There are no booleans anymore, are **student names**. If you want to get the entire `user` object then you need to restructure the database and iterate twice. Using my code, you are getting the names iterating **only** once. Your words, I quote: `display only these 5 students name :)`. You didn't say you want the entire object. – Alex Mamo May 17 '18 at 16:13
  • Ofcourse, the idea came up later and i was just asking, no doubt u deserve a medal :D So, to get entire object there should be `boolean` also in `studentsid-.....`? – jj.badweyn May 17 '18 at 16:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/171263/discussion-between-jj-badweyn-and-alex-mamo). – jj.badweyn May 17 '18 at 16:27
  • Also, any lecture where can i learn how to do it? :D to get entire object? Thanks! – jj.badweyn May 17 '18 at 16:42
  • You can post another question if you want and I'll write you how to do it. But remember, you'll need to query your database twice. – Alex Mamo May 17 '18 at 17:37
  • I'll take a look now. – Alex Mamo May 17 '18 at 17:43