Reputation: 43
With the rules below I am getting a missing or insuffiecient permissions error, but only for updates. I can create new documents, but any update writes are denied. What am I missing?
match /msgs/{msgs} {
allow create: if request.resource.data.keys().hasAll(["name", "msg", "status", "time"]) &&
request.resource.data.size() == 4 &&
request.resource.data.name is string &&
request.resource.data.msg is string &&
request.resource.data.status is string &&
request.resource.data.status == "new" || "viewed" &&
request.resource.data.time is timestamp;
allow update: if request.resource.data.size() == 1 &&
request.resource.data.keys().hasAll(["status"]) &&
request.resource.data.status is string &&
request.resource.data.status == "new" || "viewed";
}
My update code is about as straightforward as it gets:
docRef.update({
status: "viewed"
})
Upvotes: 1
Views: 78
Reputation: 43
Received the solution from the Firebase support team. It turns out that you need to make each .data.key value declaration separate and distinct. So the correct wat to accomplish this rule:
request.resource.data.status == "new" || "viewed";
is like this:
request.resource.data.status == "new" || request.resource.data.status == "viewed";
Thanks for the help everyone.
Upvotes: 0
Reputation: 15963
I think the issue here is that on update
, the size isn't "the number of fields being updated" but rather "the size of the object after the update is applied to the request, but before the update is committed". This means that request.resource.data
is "hydrated" with existing fields/values in addition to what's being written. You'll then check to ensure that only one field is changing.
This means your rules might look like:
allow update: if request.resource.data.size() == resource.data.size() &&
request.resource.data.name == resource.data.name &&
request.resource.data.msg == resource.data.msg &&
request.resource.data.time == resource.data.time &&
request.resource.data.status == "new" || "viewed";
Upvotes: 1