Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Many-to-many using Firebase

Lets say I have two kinds of objects users and accounts. Users can have many Accounts and share them with other Users. So AccountA might be available to User1 and User2. While AccountB is only available to User1. So User1 has two accounts, and User2 has one Account.

What is the "firebase" way to structure this?

I was initially thinking that the users could each store an array of accounts they belong to.

users: {
  1: {
    name: 'Ted',
    accounts: [1, 2]
  }
  2: {
    name: 'Frank',
    accounts: [1]
  }
}

accounts: {
  1: {
    name: "Checking"
  },
  2: {
    name: "Savings"
  }
}

Or the Account would have an array of users.

users: {
  1: {
    name: 'Ted'
  }
  2: {
    name: 'Frank'
  }
}

accounts: {
  1: {
    name: "Checking",
    users: [1, 2]
  },
  2: {
    name: "Savings"
    users: [1]
  }
}

I'm wondering which way lends itself for me to easily find the accounts for a user so that when Ted logs in I can list the accounts he belong to without having to pull down the entire database. For security I don't want all that data on his machine anyway.

Question #1 Would the security rules take care of this? By that I mean I'm planning to set my security rule such that users can only the accounts they belong to. I'm hoping that if I query for "/accounts" I'll get back only those accounts that the user can access... no?

Question #2 Is there a mechanism for querying for a list of items. Like "/accounts/[1,2]" so that I get back the accounts "/accounts/1" and "/accounts/2"?

Thanks for any information you can share.

like image 212
rmontgomery429 Avatar asked Jul 02 '13 01:07

rmontgomery429


1 Answers

Before jumping into specifics, there are a few things you'll want to keep in mind:

  1. You'll typically want to structure your data based on your reading patterns. So if you need to look up all accounts a user is in, you'll need to store that list somewhere. And if you want to look up all users associated with an account, you'll need to store that list somewhere as well. So regarding question #2, Firebase doesn't currently have any generic querying ability (like "/accounts[1,2]"), though this will probably come in the future.
  2. Security rules can't be used to query data either. You're either allowed to read all of the data at a location, or none of it. So regarding your question #1, the security rules won't automatically query /accounts for you.
  3. Security rules don't let you search the contents of an array for an element, but they can check for the existence of a key in an object. Therefore if users 1 and 4 have access to something, you'll probably want to store { 1: true, 4: true } rather than [1, 4].

With that in mind, I'd recommend storing the data like your first example, but without using arrays:

users: {
  1: {
    name: 'Ted',
    accounts: {
      1: true,
      2: true
    }
  }
  2: {
    name: 'Frank',
    accounts: {
      1: true
    }
  }
}

accounts: {
  1: {
    name: "Checking"
  },
  2: {
    name: "Savings"
  }
}

This will let you easily get all of the accounts for a particular user. If you need to also be able to go the other direction (all of the users for an account), you'll have to duplicate that information and store it in the accounts as well. E.g.:

accounts: {
  1: {
    name: "Checking",
    users: {
      1: true,
      2: true
    }
  },
  2: {
    name: "Savings",
    users: {
      1: true
    }
  }
}

Hope this helps!

like image 128
Michael Lehenbauer Avatar answered Oct 12 '22 13:10

Michael Lehenbauer