0

Let's say I have a collection "books" with a ridiculously big amount of children in it.

(Please this example is fictionary so don't focus on the best solution for the books)

Now, I know we could/should build the collection in such a way that each user has his/hers own collection as in:

  • books
    • userId1
      • book1
      • book2
      • book5
    • userId5
      • book2

But I wonder if having the collection like below, whit "rules" that allow users to read only the children where the ID of the user is listed under the "reader" property.

  • books
    • book1
      • reader
        • userId1
        • userId2
        • userId4
    • book2
      • reader
        • userId1
    • book5
      • reader
        • userId3

If this rule is possible, could we call the reference mDatabase.child("books") and receive only a snap of the books the user can read instead of ALL books?

GV3
  • 491
  • 3
  • 16

1 Answers1

2

No, that is not possible, since Firebase rules do not act as filters. If you try to request all books in your example, but the read rules say you do not have access to one of them, then the user won't be able to request the books at all, and the entire request will fail.

The recommended way to deal with this kind of thing is to do your reader listing differently. A valid structure would be something like this:

  • books
    • book0
    • book1
  • readers
    • user0
      • reading
        • book0
        • book1
    • user1
      • reading
        • book1

Because you know the user ID of a user, looking up a user is cheap. Then checking out which books a user is reading is cheap as well, because that's in the user object. If you have the IDs of the books the user is reading, you can fetch those books by their IDs separately without having to request the entire array of books.

Performance is not a problem anymore in that scenario. Looking up an object by it's index in an array, or it's key in an object is fairly cheap.

  • Thanks Rick, I understand. Another small question, If I'm displaying the list of books a user is reading and I want in that list to show data that is saved in the books collection, constantly changing, and unique for each user... like the total amount of friends reading that particular book. What would it still be cheap to do queries for each of the items of the user's list? I still find it very difficult to enter into the data structure mindset of Firebase for such relational per-user-unique information. – GV3 Sep 01 '16 at 12:26
  • Well, I'm not sure about the complexity of such a query. Representing friendships is actually quite hard, because it's a prime example of relational data: a friendship does not belong to one of the friends involved, it's a shared relation. If you care about performance, save the friends of each user under each user object, which would mean a duplication of the data. If you care about correctness and making sure your data is not corrupted, save it as a separate entity. You can then request the friends of a user and what books the friends are reading and perform calculations on that data. – Rick Lubbers Sep 02 '16 at 15:44