I'm trying to use the size of the path in the firestore rules, but can't get anything to work, and can't find any reference in the firestore docs on how to do this.
I want to use the last collection name as a parameter in the rule, so tried this:
match test/{document=**}
allow read, write: if document[document.size() - 2] == 'subpath';
But .size() does not seem to work, neither does .length
This can be done but you first have to coerce the Path to a String.
To get the Path of the current resource, you can use the __name__
property.
https://firebase.google.com/docs/reference/rules/rules.firestore.Resource#name
For reference, resource
is a general property that is available on every request that represents the Firestore Document being read or written.
https://firebase.google.com/docs/reference/rules/rules.firestore.Resource
resource['__name__']
The value returned by __name__
is a Path, which is lacking in useful methods, so before you can use size
you will need to coerce the Path to a String.
https://firebase.google.com/docs/reference/rules/rules.String.html
string(resource['__name__'])
Once converted to a string, you can then split
the string on the /
operator and convert it into a List
of String path parts.
https://firebase.google.com/docs/reference/rules/rules.String.html#split
string(resource['__name__']).split('/')
Now you can retrieve the size of the List using the List's size
method.
https://firebase.google.com/docs/reference/rules/rules.List#size
string(resource['__name__']).split('/').size()
One of the challenging things about Firestore rules is that there's no support for variables so you often will repeat code when you need to use a result more than once. For instance, in this case, we need to use the result of the split twice but cannot store it into a variable.
string(resource['__name__']).split('/')[string(resource['__name__']).split('/').size() - 2]
You can DRY this up a bit by making use of functions and using the parameter as your variable.
function getSecondToLastPathPart(pathParts) {
return pathParts[pathParts.size() - 2];
}
getSecondToLastPathPart(string(resource['__name__']).split('/'))
Tying it all together for your solution, it would look like this...
function getSecondToLastPathPart(pathParts) {
return pathParts[pathParts.size() - 2];
}
match test/{document=**} {
allow read, write: if getSecondToLastPathPart(string(resource['__name__']).split('/')) == 'subpath';
}
Hope this helps!
You can learn rules here
// Allow reads of documents that begin with 'abcdef'
match /{document} {
allow read: if document[0:6] == 'abcdef';
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With