1

I am using Firebase Realtime DB. There is a list of 'users' at the top level and each user has a list of books. I am trying to iterate to get all the books from all users but I am having an issue using the firebase db call to do so. I am trying to do so with the following but I believe I am doing something wrong in this call to achieve what I am going after.

firebase.database().ref('/').on('value', (snapshot) => {
    snapshot.forEach((child) => {
        console.log(child.child('books').val());
    });
})

screenshot of DB structure

3
  • I'll assume that the missing ). after ('books' is a typo in the question only. If that's indeed the case, what's the problem when you run this code? What does it log? And what do you want it to log instead? Commented Dec 29, 2019 at 5:10
  • Hi @FrankvanPuffelen, sorry, yes -- just a type transferring it over to stackoverflow. I am getting null logged in the console from the code Commented Dec 29, 2019 at 5:20
  • You're not taking the users node into account. So you'll either need to do that in the callback, or read one level lower in the tree: firebase.database().ref('users').... I'll write an answer below too. Commented Dec 29, 2019 at 5:32

1 Answer 1

1

Right now you're reading the root node, and then iterating over its child nodes. That means that child is a snapshot of the key and value of the users node, not of the child nodes under that. You can easily verify that by logging the key of the child node:

firebase.database().ref('/').on('value', (snapshot) => {
  snapshot.forEach((child) => {
    console.log(child.key);
  });
})

This will log:

users

And since the users node does not have a books property, the child.child('books').val() is null.


There are two possible solutions:

  1. Read only the data under the users node, which you do with:

    firebase.database().ref('/users').on('value', (snapshot) => {
      snapshot.forEach((user) => {
        console.log(user.child('books').val());
      });
    })
    
  2. Handle the users node in your callback, with something like:

    firebase.database().ref('/').on('value', (snapshot) => {
      snapshot.child('users').forEach((user) => {
        console.log(user.child('books').val());
      });
    })
    

In either case you'll likely also want to iterate over the books, so will need a/another nested loop. Something like:

firebase.database().ref('/users').on('value', (snapshot) => {
  snapshot.forEach((user) => {
    snapshot.child('books').forEach((book) => {
      console.log(book.val());
      // or: console.log(book.child('author').val());
    });
  });
})
Sign up to request clarification or add additional context in comments.

3 Comments

this is great, thanks Frank! I just realized, like you mentioned, I will need another nested loop to iterate through the books. Do you think it makes sense, performance wise, to have a new table called "all_books" that lives alongside "users" and when a user adds a book, I have another call that adds it to "all_books" table so that table has a copy of all books? Otherwise, I'd have to iterate that loop, which I'm anticipating might get large with lots of users and books
In handling data from Firebase, the majority of time will be spent in the amount of data you transfer from the server to the client. If you want to print/process all of them, the current structure is the same in that sense as having a single long list. If you want to be able to show the books for one user only, your current structure is actually already nicely partitioned by user. But if you want to show a list of some of the books across all users through a query, it's probably better to have a single list of books and a UID property for each.
thanks so much, Frank -- great explanation! -- just accepted as answer but I don't have enough reputation (new user) to up vote. Thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.