0

I want to write a shopping-list app, where users will be able to give read-only or read-write permissions to other users.

I plan the database to look like this:

{
    "lists": {
        "1": {
            "title": "List #1",
            "items": [...],
            "owner": "user1",
            "read_only_access": [ {"user2": true} ],
            "read_write_access": [ {"user3": true} ],
        },
        "2": {
            "title": "List #1",
            "items": [...],
            "owner": "user1",
            "read_only_access": [ {"user3": true} ],
            "read_write_access": [],
        },
        "3": { ... }
    },
    "users": {
        "user1": {
            "name": "John",
        },
        "user2": { ... },
        "user3": { ... }
    }
}

How do I define the access rules for the "lists" tree, so that:

  • The owner will have read-write access to all his lists
  • Users in the read_only_access list will have read access
  • Users in the read_write_access list will have read-write access
  • Users who are neither the owner of the note, nor in the read_only_access and read_write_access lists of the note - won't have even read access to it

Thanks!
Slavik

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Slavik N
  • 4,705
  • 17
  • 23

1 Answers1

0

Database

{
  "list-users" : {
    "1": {
      "user2" : {
        "access" : { "read" : true, "write": false }
      },
      "user3" : {
        "access" : { "read": false, "write" : true }
      }
    },
    "2": {
      "user3" : {
        "access" : { "read" : true, "write": false }
      }
    }
  },
  "lists" : {
    "1": {
      "items": [ ... ],
      "owner" : "user1",
      "title" : "List #1"
    },
    "2": {
      "items": [ ... ],
      "owner" : "user1",
      "title" : "List #2"
    },
    "3": {
      "items": [ ... ],
      "owner" : "user1",
      "title" : "List #3"
    }
  },
  "users" : {
    "user1" : { "name" : "John" },
    "user2" : { "name" : "Jane" },
    "user3" : { "name" : "Joel" }
  }
}

Rules

{
  "rules": {
    "list-users": {
      "$lid": {
        "$uid": {
          ".write": "auth.uid === root.child('lists/$lid/owner').val()",
          ".validate": "newData.child('access').hasChildren(['read', 'write'])"
        }
      }
    },
    "lists": {
      "$lid": {
        ".read": "data.child('owner').val() === auth.uid || root.child('list-users').child($lid).child(auth.uid).child('/access/read').val() === true",
        ".write": "data.child('owner').val() === auth.uid || root.child('list-users').child($lid).child(auth.uid).child('access/write').val() === true"
      }
    },
    "users": {
      "$uid": {
        ".read": "auth !== null",
        ".write": "auth.uid === $uid"
      }
    }
  }
}
Callam
  • 11,409
  • 2
  • 34
  • 32
  • You can use either, "===" is the strict operator https://stackoverflow.com/questions/359494/which-equals-operator-vs-should-be-used-in-javascript-comparisons – Callam Aug 19 '17 at 14:27