0

I am writing an application that handles organization members and payments. I have the following entities:

Organization---+
               |
               +---Members-----+
               |               |
               |               +---Children
               +---Accounts
               |
               +---Payments

There can be >100,000 payment per organization, but only few members and Accounts. When a member is logged-in he can see only his payments. When admin is logged in he should be able to access all data.

The questions are:

  1. Should I keep hierarchical structure of the organization or should I flatten each entity?
  2. In case I would like to keep the structure hierarchical, is it possible to get an Organization with only partial sub-collections (not all members and not all payments)

Thanks.

AL.
  • 36,815
  • 10
  • 142
  • 281
Ronen
  • 807
  • 1
  • 13
  • 33
  • Please for future questions share real JSON, not an approximation/model. Now you have two answers that *might* both be correct and we're spending time trying to figure out what the other means, instead of helping you. – Frank van Puffelen Feb 27 '17 at 15:06

2 Answers2

6

One thing to always keep in mind with Firebase's real time database is the amount of data you're retrieving and the amount of data you're making the database consider.

If you make the database consider 100K payments to show <10 payments for the current user, you've wasted a lot of resources. I wrote more about this here: Firebase Scalability Limit and Firebase Performance: How many children per node?.

If you model the payments for each user separately, you'll drastically reduce the amount of data the server has to consider. This improves scalability, although of course not linearly.

If the admin user needs to see all data, I'd recommend that you first make them select a user. After that they'll follow the same access pattern as regular users.

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
1

You should keep your structure flat and as denormalized as possible. Querying the parent node will load all the child nodes and data.

Yes, you can still use query/filter using the SDK available.

alltej
  • 6,787
  • 10
  • 46
  • 87
  • 1
    I'm not immediately disagreeing, but can you explain *why* you think the data should be kept as a flat list of payments? – Frank van Puffelen Feb 26 '17 at 21:20
  • Here's a link to designing firebase nosql database https://firebase.google.com/docs/database/web/structure-data – alltej Feb 26 '17 at 21:42
  • 1
    I'm intimately familiar with that documentation. But I don't understand what part of it you think applies here. Combining different data types in a single hierarchy is almost aways a bad idea. But as far as I can see that doesn't apply here. Nesting collections is quite common in Firebase realtime database and quite often the best solution. – Frank van Puffelen Feb 26 '17 at 22:22
  • You just want to avoid deeply nested data because it can result to performance issues/bottlenecks later on. Just an example, in your case above (although not a lot of members or accounts) , you want to query only the members profile info and not really interested on the accounts and payments. If they were nested, you will not only get the member node but you will also get all the children nodes(accounts and payments). To avoid this nesting, create a member and account association and account and payment association. Having a shallow data structure will make querying very efficient. – alltej Feb 27 '17 at 12:41
  • To get the members for an organization, you'd query `/Organization/Members`. That way you'll only get members and the database doesn't even have to consider payments and accounts. Now we can't be sure what OP has under each of those item types, so he might still be nesting entity types. I left a comment to that effect. – Frank van Puffelen Feb 27 '17 at 15:06
  • Here's a link in youtube that can help explain firebase database design best practices - https://www.youtube.com/watch?v=4vnoPtSg4uU – alltej Feb 27 '17 at 15:42