Jennie Lyn Shapiro
Jennie Lyn Shapiro

Reputation: 113

Sharing Between Clients in Firebase

I would like to know if it is possible to implement Firebase security in such a way as to allow a each user of my app full access to data in their own location, while enabling the user them self's to enable or disable the type of access from other users to their own data? Or basically, is it possible to implement simple sharing, Dropbox or Google Drive style, among the users of my app, in such a way that it is strictly enforced?

Upvotes: 2

Views: 2319

Answers (1)

Kato
Kato

Reputation: 40582

Since Firebase security rules allow you to reference data in Firebase, you can base the security rules on anything you can create data for. So yes, you could allow a user to share their own data in just about any way you could scheme up.

To contrive a simplified example based on the dropbox idea, I could have a "shares" folder under my data, and a security folder where I store access rights:

/security/$user_id/$friend/...   // where I put the access rights
/folders/$user_id/shares/...     // where I put the shared files

Now I could control access to it by putting user names and a list of folders they can access into my Firebase data:

/security/$user_id/$friend_id = /never/gonna/give/you/up = true

Now in my security rules, I can write something like this:

{
   "security": {
      "$user_id": { // only authenticated user may read/write his rules
         "shares": {
            ".read": "auth.id === $user_id",
            ".write": "auth.id === $user_id"
         }
      }
   }
   "folders": {
      "$user_id": {
         // only authenticated user may read/write his folders
         ".read": "auth.id === $user_id",
         ".write": "auth.id === $user_id",
         "shares": {
            // but my friends can read data in shares
            ".read": "root.child('security/'+$user_id+'/'+auth.id+'/shares').val() === true"
         }
      }
   }
}

Note that one limitation on this (for the time being) is that security rules cannot work recursively or in any nested manner. However, since the rules are permissive (if any parent of the path allows access, then it is allowed), you can work around this.

You could need to place a hard limit on the max number of child paths and manually declare them in the rules like so:

// allow sharing up to 3 levels deep
"shares": {
   ".read": "root.child('security/'+$user_id+'/'+auth.id+'/shares').val() === true",
   "$child1": {
      ".read": "root.child('security/'+$user_id+'/'+auth.id+'/shares/'+$child1).val() === true",
      "$child2": {
         ".read": "root.child('security/'+$user_id+'/'+auth.id+'/shares/'+$child1+'/'+$child2).val() === true",
         "$child3": {
            ".read": "root.child('security/'+$user_id+'/'+auth.id+'/shares/'+$child1+'/'+$child2+'/'+$child3).val() === true",
         }
      }
   }
}

Not the prettiest thing to look at, but a good temporary solution until Firebase gets some nesting features.

Upvotes: 5

Related Questions