Search code examples
firebase-realtime-databasefirebase-security

How invalidate other nodes besides that user node?


I have this db:

db
 \
  users
   \
    $uid
     \
      email: "[email protected]"
     \
      username: "John"

I'm trying to not let the users to add other fields than email and username, so I have added:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid",
        "email": {
          ".validate": "newData.isString()"
        },
        "username": {
          ".validate": "newData.isString()"
        },
        "$other": { ".validate": false } //Here!!!!!!!
      }
    }
  }
}

Which works correct. What I also want to do, is to not allow the users to create other nodes within the users node other than the UID. So I have also added the above validation:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid",
        "$other": { ".validate": false } //Works
      },
      "$other": { ".validate": false } //Doesn't work
    }
  }
}

But this operation fails:

I get Error saving rules - Line 9: Cannot have multiple default rules ('$uid' and '$other').

So how to invalidate the addition of other nodes inside the users node, when using wild cards?


Solution

  • You don't need the highest-level $other in your rules. Since you check ".write": "$uid === auth.uid", inside the $uid node, users already can only write to their own node - and not create other sibling nodes of that.

    So you'll want to use the rules as this:

    {
      "rules": {
        "users": {
          "$uid": {
            ".read": "$uid === auth.uid",
            ".write": "$uid === auth.uid",
            ...
            "$other": { ".validate": false }
          },
        }
      }
    }