Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase security rules: restrict write only to this uid, except for a couple of fields

In Firebase I have a users "node", which looks like:

users: {
  someUid: {
    username: 'someUsername'
    activeConversations: {},
    profile_picture: ''
    ... lots of other children
  },
  ...
},
anotherNode: {

},
... hundreds of other nodes

My rules right now:

{
  "rules": {
    ".read": true,
    ".write": true,
    "users": {
      ".indexOn": [
        "username"
      ]
    },
    "friendRequests": {
      ".indexOn": [
        "timeSent"
      ]
    }
  }
}

What I want to do is restrict child's access in the users "node" only to the client who owns the child. So for instance, the someUid child should only be writeable by the client with uid someUid. Other "node" like anotherNode can be writeable / readable by any logged-in client. Also, any logged-in client should be able to write on profile_picture and activeConversations in the users doc.

How can I achieve that without having to put a read/write rule on every single node?

Thank you

like image 323
Dan P. Avatar asked May 16 '17 10:05

Dan P.


People also ask

Is Firebase UID safe?

The correct way to secure user related resources is via a Firebase ID token. Database/Storage rules already rely on this mechanism. You cannot just rely on the correct user ID being provided. That provides no security.

Why is it important to write security rules in Firebase?

Firebase Security Rules stand between your data and malicious users. You can write simple or complex rules that protect your app's data to the level of granularity that your specific app requires.

How do I change my security rules on firestore?

Use the Firebase console To set up and deploy your first set of rules, open the Rules tab in the Cloud Firestore section of the Firebase console. Write your rules in the online editor, then click Publish.

How do I set Storage rules in Firebase?

You can edit these rules by selecting a Firebase app in the Firebase console and viewing the Rules tab of the Storage section.


1 Answers

I think @Bradley Mackey was nearly there but just needed a small tweak.

{
  "rules": {
    "users": {
      ".indexOn": ["username"],
      // wildcard, matches any node under 'users'
      "$someUid": {
        "$other" : {
          ".read": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid", 
          ".write": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid", 
        }
      }
    },
    "$anythingelse": {
      ".read": "auth != null",
      ".write": "auth != null",
    }
  }
}

The ".validate": field ensures that a field matches a certain format. The read and write here should give everyone read and write access if the field is profile_picture or activeConversations, and give the user access to everything else.

EDIT:

I added in another rule that would allow read-write access to any signed in user to any of the non-users nodes.

like image 65
Adam Brocklehurst Avatar answered Sep 23 '22 04:09

Adam Brocklehurst