Rebe
Rebe

Reputation: 157

Firestore Security Rules: hasOnly not working?

I want to update only some fields in the document so I found hasOnly function in the documentation here but it's not working, for example, the rule below not working

function isValid(data){
   return data.keys().hasOnly(['name','email','password'])
}

and when I update in client SDK

firestore.document("users/user_doc")
            .update(mapOf(
                "name" to "Jack",
                "email" to "[email protected]",
                "password" to "12345"
            )).addOnCompleteListener {
                if (it.isSuccessful){
                    Log.d("app", "success")
                }else{
                    Log.d("app", "failed")
                }
            }

but it shows an error that missing permission

and also hasAll function always return true! So does this function exist? Why it is not working?

Thanks.

Upvotes: 4

Views: 1122

Answers (2)

Renata Portela
Renata Portela

Reputation: 186

An alternative is:

allow update: if request.resource.data.diff(resource.data).changedKeys().hasOnly(["name", "email", "password"]);

New improvements to Firestore Security Rules

Upvotes: 15

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

Keep in mind that request.resource contains the document as it will appear if the write operation succeeds. It contains existing fields too, not just the ones that you're updating.

If there are more fields, you will need to check whether those are unmodified by the write operation. So you'd check that they have the same value in the request.resource and resource. I often use a function like this in my rules for that:

function isUnmodified(key) {
  return request.resource.data[key] == resource.data[key]
}

If your document has one additional field created, you'd ensure that is unmodified with:

return data.keys().hasOnly(['name','email','password', 'created']) && isUnmodified('created')

Upvotes: 14

Related Questions