If you want to show a list to the user of all TODO lists she has access to, I would store that list in Firebase.
Stealing from Mathew's sample data:
{
users: {
user1Id: {
//other data
lists: {
list1Id: true,
list5Id: true
}
}
},
lists: {
list1Id: {
//other data,
memberships: {
user1Id: true
}
}
}
}
So in the above snippet, you only have to load /users/user1Id
to know what lists he has access to. You don't need to do any query to determine that, so loading the "list of user1's lists" is dead-cheap. You could even store the information that you want to display for each list in the user's data too, preventing the need for a lookup.
{
users: {
user1Id: {
//other data
lists: {
list1Id: "Groceries for BBQ",
list5Id: "4th of July parties to go to"
}
}
},
lists: {
list1Id: {
title: "Groceries for BBQ",
//other data,
memberships: {
user1Id: true
}
}
}
}
Note that in both cases we are duplicating data. I recommend doing this in many cases, since it speeds up reading the data for a specific use-case. But of course it comes at a cost of having to write the data to multiple places when you first add it. And you'll also have to consider if/how you want to update all instances of that data when e.g. the list title changes.
Read this article for a nice introduction on the topic: https://medium.com/@collardeau/es6-promises-with-firebase-76606f36c80c or this answer for my input for that article: How to write denormalized data in Firebase
Update
I just realize that you should probably normalize this data a bit. Firebase recommends that you don't build nests, when they are not needed. In this case, you might want to see a user's profile data, and you wouldn't need her lists. Or the user just wants to see her lists, not her profile data. So a more normalized model would be:
{
users: {
user1Id: {
//profile data
}
},
users_lists: {
user1Id: {
list1Id: "Groceries for BBQ",
list5Id: "4th of July parties to go to"
}
lists: {
list1Id: {
title: "Groceries for BBQ",
//other data,
memberships: {
user1Id: true
}
}
}
}
It's the exact same data as before, but now the users_lists
is in a separate top-level data structure.
Of course whether this structure is better depends on the use-cases you want to cater for. If you always show the user's profile data and todo-lists in one screen, the former is slightly more efficient. But either data structure is more efficient than the one most developers think of first select * from all_todo_lists where user_id = me
. :-)