1

I am trying to figure out best practices for a Firebase Realtime database structure when securing data. I have read about how to secure the database using Firebase Realtime Database Rules.

For example: A user adds "notes" and shares those "notes" with other users (members) who can then edit and comment those "notes". Lets consider a storage structure like the one below:

-categories
  -uuid-cat1
    -data
      title: "my category 1"
    -members
      author: "uuid-user1"
-notes
  -uuid-note1
    -data
      title: "Hello World!"
      categoryId: "uuid-cat1"
      -comments
         -uuid-comment1
           title: "Can you explain?"
           author: "uuid-user2"
         -uuid-comment2
           title: "Certainly!"
           author: "uuid-user1"
    -members
      author: "uuid-user1"
      uuid-user2: "uuid-user2" //UPDATE 2 - This is another user with access to the note
  -uuid-note2
    -data
      title: "Hello Universe!"
      -categoryIds
         uuid-2: "uuid-cat2"
    -members
      author: "uuid-user2"
-users
  -uuid-user1
    name: "Jane"
  -uuid-user2
    name: "Jane"

Users only have access to notes or categories if they are listed as "members/author" or "members/user-id". This is enforced by Firebase Realtime database Rules.

Would this work in on a larger scale? Let's say we store 200 000 notes.

When requesting to read all "notes" from the database, would this structure cause a performance issue in Firebase - since Firebase will have to loop thru all "notes" to determine access before returning the list?

Is there a better way (best practice) to structure the data?

UPDATE

My rules would look something along the lines of:

{
  "rules": {
    "notes" : {
      //indexes
      ".indexOn": ["data/title", "members/author"],
      //access
      ".read": "
        auth.uid != null &&
        query.orderByChild == 'members/author' && query.equalTo == auth.uid
      ",
      ".write": "
        auth.uid != null && 
        query.orderByChild == 'members/author' && query.equalTo == auth.uid
      ",
      "$noteid": {
        "data": {
          "title": {
            ".validate": "newData.isString() && newData.val().length > 0"
          }
        }, 
        "members" : {
          ".read" : true, 
          ".write": true, 
          //validation
            ".validate": "newData.hasChildren([
                'author'
            ])",
          "author" :{
            ".validate": "newData.isString()"
          }
        }
      }    
    },
    "categories": {
      //The same type of rules as for "notes"
    },
    "users": {
      "$userid": {
        ".read": "$userid === auth.uid",
        ".write": "$userid === auth.uid"
      }
    }
  }
}

My code would look somethin along the lines of:

const myUid = firebase.auth().currentUser.uid;
const ref = firebase.database().ref('notes');
ref.orderByChild('members/author').equalTo(myUid).on('value', (snapshot) => {
  console.log(snapshot.key)
  const notesArray = []

  snapshot.forEach( (childSnapshot) => {
    notesArray.push({
      id: childSnapshot.key,
      data: childSnapshot.val()
    });
  });

  console.log(notesArray);
}
Kermit
  • 2,865
  • 3
  • 30
  • 53
  • 1
    Please show the actual code and security rules that you're asking about. Without that, it is hard to answer any questions about their performance. – Frank van Puffelen Nov 10 '18 at 15:26
  • Hello Frank, thank you for the reply! I have updated the post to show some conceptual example code. Not sure if the access rules are 100% correct though. – Kermit Nov 11 '18 at 09:40
  • 1
    That query should work fine on a few hundred thousand child nodes. See https://stackoverflow.com/questions/28857905/how-many-records-rows-nodes-is-a-lot-in-firebase. But since you can only have one author per node, I'd recommend storing it in a `/AuthorNodes/$uid: { note1id: true, node2id: true }` format too. – Frank van Puffelen Nov 11 '18 at 15:08
  • Hi Frank - Thank you for the prompt reply! I am actually planning on adding more editors alongside author, hence the structure. :) Glad to hear the query should work fine, even with large amounts of data! I have made an update to show editors alongside authors. – Kermit Nov 11 '18 at 17:40

0 Answers0