evdama
evdama

Reputation: 2206

Firestore / Security Rule / Function / Fieldname as Parameter?

I would like to have a firestore security rules function I can use to check wheter or not incoming data to a particular document field (request.resource.data.<some_field_name>) is of a certain type e.g. string.

Use Case Explained via simple Example

For a particular field called firstName it can easily be done like this:

rules_version = '2'
service cloud.firestore {
    match /users/{uid} {
        allow read
        allow write: if isString()
      }
}

function isString() { return request.resource.data.firstName is string }

What works in Practice but isn't practical

However, I would have to hardcode firstName inside the function so the function isn't generic i.e. if I wanted to also check whether or not another field on this document e.g. lastName is of type string I'd have to have the basically same function again except this time I'd hardcode lastName: function isString() { return request.resource.data.lastName is string } then rename the functions accordingly so I end up with something like this:

rules_version = '2'
service cloud.firestore {
    match /users/{uid} {
        allow read
        allow write: if firstNameisString() || lastNameisString()
      }
}

function firstNameisString() { return request.resource.data.firstName is string }
function lastNameisString() { return request.resource.data.lastName is string }

What I want to do

but what I really want is something where I could provide the fieldName as a parameter so I could do this, thereby not having to duplicate code for every fieldName I'd like to validate but really just have one function for n fieldNames:

rules_version = '2'
service cloud.firestore {
    match /users/{uid} {
        allow read
        allow write: if isString(fieldName)
      }
}

function isString(fieldName) { return request.resource.data.fieldName is string }

Am I missing something really obvious or why isn't that syntax possible as the firebase console or the rules emulator isn't allowing it?

Upvotes: 0

Views: 474

Answers (2)

evdama
evdama

Reputation: 2206

Excellent, thanks much, that worked, I used it like so

match /public/{uid} {
        allow read
        allow write: if isString('userProfession')
      }

i.e. the fieldName is a string thus in single quotes.

Upvotes: 0

Louis Coulet
Louis Coulet

Reputation: 4631

According to the documentation, resource.data has type rules.Map, which you can access with the [] operator or the get method:

function isString(fieldName) { 
    return request.resource.data[fieldName] is string;
}

Upvotes: 3

Related Questions