hotpopper80
hotpopper80

Reputation: 49

How do I set firebase database rules to not allow delete or update of children?

I have the following Firebase database rules, but this only allows data to be written once. Nothing after that.

Edit. I want to make sure no data ever gets deleted, also.

{
 "rules": {
   "$uid": {  //userIDTom
     ".read": "true",
     ".write": "!data.exists()"
     }
   }
 }

I want to be able to write a child only if that child does not exist.

Example,

          "userIDTom" : {
        "testKey1" : "test1",
        "testKey2" : "test2",
        "testkey3" : "test3"
      }
    }
  }

All the above will be written into "UserIDTom"

But in the next example,

    "userIDTom" : {
            "testKey4" : "test4",
            "testKey2" : "update",
            "testkey5" : "test5"
          }
        }
      }

In the above example, only testKey4 and testKey5 will be written. testKey2 will be skipped because it already exists. Note it should still be skipped even if it's value is different. In other words, only allow writing of new keys.

End result should be:

          "userIDTom" : {
        "testKey1" : "test1",
        "testKey2" : "test2",
        "testkey3" : "test3",
        "testKey4" : "test4",
        "testkey5" : "test5"
      }
    }
  }
}

}

Upvotes: 4

Views: 1761

Answers (3)

Display name
Display name

Reputation: 467

I believe what you want is : !data.exists() && newData.exists()

or in your format:

{
 "rules": {
   "$uid": {  //userIDTom
     ".read": "true",
     ".write": "!data.exists() && newData.exists()"
     }
   }
 }

As the website below describes, data refers to the data that is in the database right now. Therefore, when we say data.exists() that means that the data is not null and !data.exists() means data is null. With this, we can allow either create or update (not having this rule allows both create and update).

Then, newData refers to what our data will look like after it has been added to the database. The newData is the merging of our current data and the data that we are pushing to the database. By having no newData rules, we allow creating, updating and deleting. By saying newData.exists() we say that we only allow creating or updating data. Or, after the write is finished, there must be data here. If we say !newData.exists() then we are only allowing deletes, or writes that leave us with no data existing at this location.

Fore more info, see : Firebase rules and conditions

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

In the above example, only testKey4 and testKey5 will be written. testKey2 will be skipped because it already exists

What you're describing here is not how Firebase security rules work, they don't filter data: not when reading, nor when writing. When you perform a write operation, that entire operation is either accepted or rejected.

So if userIDTom already exists in your examples, then any write to/under it will be rejected. If userIDTom doesn't exist yet, the write will be allowed.


If you want to reject a write if any of the child nodes it writes to already exists, put the .write rule one level lower:

{
  "rules": {
    "$uid": {  //userIDTom
      ".read": "true",
      "$property": {
        ".write": "!data.exists()"
      }
    }
  }
}

Upvotes: 1

Ericgit
Ericgit

Reputation: 7043

Existing Data vs. New Data

To illustrate, this rule would allow us to create new records or delete existing ones, but not to make changes to existing non-null data:

data variable is used to refer to the data before a write operation takes place. Conversely, the newData variable contains the new data that will exist if the write operation is successful

// we can write as long as old data or new data does not exist
// in other words, if this is a delete or a create, but not an update
".write": "!data.exists() || !newData.exists()"

Learn all about Firebase Rules, And writing too

Upvotes: 0

Related Questions