Reputation: 49
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
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
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
Reputation: 7043
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