user14554516
user14554516

Reputation:

onDataChange() method is never reached

I am trying to retrieve data from Firebase, but I don't know how. I have the following data structure in Firebase [1]: https://i.sstatic.net/vN7Ge.png:

![enter image description here][1]

I can retrieve the category title(sleep, Stress Relief, and Relax), but don't know how to retrieve the author.

dataSnapshot.child("author").getValue(String.class)) ; doesn't work.

.

    databaseReference = FirebaseDatabase.getInstance().getReference().child("Category");
        }
    
        public void getDataFromFirebase() {
            List<ParentItem> parentItemsList = new ArrayList<>();
            databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                       String category = dataSnapshot.child("Category").getValue(String.class));
  String author = dataSnapshot.child("author").getValue(String.class));
                        
                    }
                    Log.d("TAG", "onDataChange: "+ parentItemsList);
                }
 

UPDATE now I have the following code to retrieve data, but onDataChange () is never reached.

list.add("Milena"); // this word shows in recyclerview
    databaseReference = FirebaseDatabase.getInstance().getReference().child("Category");
    databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
list.add("M");
            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                String category = ds.child("Category").getValue(String.class);
                list.add(category);
                for (DataSnapshot data : dataSnapshot.getChildren()) {
                    author = data.child("author").getValue(String.class);
                    list.add(author);
                }
            }
        }

firebase rules:

{
  "rules": {
    ".read": "auth==true",
    ".write": "auth==true"
  }
}

I have line list.add("Milena") to make sure the problem is with firebase, not the recycler view itself. Recycler view shows only the word "Milena". And I have line as the first line of OnDataChange method list.add("M"). The recycler view doesn't shows the letter.

I already added google-services.json file to my app and added this line to manifest <uses-permission android:name="android.permission.INTERNET"/>

Why I can't still retrieve data?

Upvotes: 0

Views: 287

Answers (3)

Alex Mamo
Alex Mamo

Reputation: 138924

To solve this issue you have to iterate through the children twice, as seen in the following lines of code:

DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference categoryRef = db.child("Category");
categoryRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            DataSnapshot snapshot = task.getResult();
            for (DataSnapshot categorySnapshot : snapshot.getChildren()) {
                String categoryName = categorySnapshot.getKey();
                Log.d("TAG", categoryName);

                for (DataSnapshot ds : categorySnapshot.getChildren()) {
                    String author = ds.child("author").getValue(String.class);
                    Log.d("TAG", author);
                }
            }
        } else {
            Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
        }
    }
});

But be aware that a child as Category: "Sleep" should not exist on the same level as 1, 2, and so on. Since the name of the category already exists as the key of a node, please remove those records:

enter image description here

In this way, you'll avoid a ClassCastException, as at the same level you have an object with two properties and a String one. So once you remove those children, the above code will work perfectly fine. If you however need a node to contain that information, I recommend you create a top-level node that will contain only the name of the categories.

Upvotes: 0

I think that the problem is your reference points to Category and you want the author. Between category and authors there are 2 children ("Sleep" and "1"). So, I think the best to do is change this line:

databaseReference = FirebaseDatabase.getInstance().getReference().child("Category");

in this:

databaseReference = FirebaseDatabase.getInstance().getReference().child("Category").child("Sleep").child("1");

Upvotes: 0

Fakhri Khairi
Fakhri Khairi

Reputation: 81

If you want get field author, you can more loop for dataSnapshot like this

for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
     String category = dataSnapshot.child("Category").getValue(String.class));
     for(DataSnapshot data : dataSnapshot.getChildren()) { 
         String author = data.child("author").getValue(String.class));
     }
}

hope this can solve your problem :)

Upvotes: 1

Related Questions