Firebase Firestore rules path in production
See original GitHub issue[REQUIRED] Environment info
firebase-tools: 8.16.2
Platform: macOS
[REQUIRED] Test case
Following the docs, I tried to debug the path
When I’m using the emulator
locally, the path is like /databases/$(database)/documents/col1/doc1/col2/doc2/col3/doc3...
so this resource['__name__'][0]
will be databases
and resource['__name__'][4]
will be doc1
for example, this test
function will return true
(locally, using the emulator):
function test() {
return string(resource['__name__'][4]).matches('doc1');
}
Or:
function test() {
return string(resource['__name__'][0]).matches('databases');
}
But, when I deploy
the rules, the test
function becomes false
Is it because the path in production is different? If so, how can I see it? is there any example for a production path…
UPDATE:
I tried the Rules Playground in Firebase Console and noticed that test
function is true
only if it’s used for the first or second sub-collection, but it becomes false when it’s used for the third sub-collection (e.g. col3) and throws this error:
Error running simulation — Error: simulator.rules line [xx], column [xx]. Null value error.
the error seems to be pointing at resource['__name__']
In the emulator, test
function is always true
no matter where it’s used
[REQUIRED] Steps to reproduce
When it’s deployed
, test
function becomes false
if it’s used for a 3rd sub-collection.
full example:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /cols1/{col1} {
allow read, write: if true;
match /cols2/{col2} {
allow read, write: if test(); // this is true
function test() {
return string(resource['__name__'][0]).matches('databases');
}
match /cols3/{col3} {
allow read, write: if test(); // this is false
function test() {
return string(resource['__name__'][0]).matches('databases');
}
}
}
}
}
}
[REQUIRED] Expected behavior
Expected the path to be the same in the emulator and production
[REQUIRED] Actual behavior
Seems there’s a different in the path between the emulator and production
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:9 (5 by maintainers)
I believe you’re experiencing the error because
resource
variable isnull
in production in the request you’re testing. Remember in rules that theresource
variable is only available if the document already exists in the database – e.g. for aget
request,resource
will be null unless the documentcols1/doc1/cols2/doc2/cols3/doc3
exists in your database. You may have this already in your emulator but not in the production database.Since you only need the path of the document, I’d suggest you use
request.path
instead. That variable is ALWAYS available and works just likeresource['__name__']
. For example,string(request.path[0])
gives youdatabase
.Also, FYI, you can use the right panel to the detailed sub-expressions in the Rules Playground. For example, the following screenshot shows the value returned by the
string(...)
call.@adotnusiyan I did try your example in Firebase Console in the Rules Playground and I tested against all three levels. I found that if
cols1/doc1/cols2/doc2/cols3/doc3
does not exist, then the function will throw a null value error. Once I create it in the Data tab in console, running the simulation again gives metrue
. This is consistent with top and second levels.I don’t want to jump into conclusions, but please make sure to double check the spelling of the paths in the Playground and Data tab to make sure they match exactly. If the issue persists, the best way for us to move forward is for you to create a minimal repro (e.g. a GitHub repository with sample rules and a script that reads data from the 3rd collection, on web or Node.js client (not admin)). Since there is nothing to be done in the Firebase CLI or Emulator Suite, I’ve also closed this issue – production issues are better handled by Firebase Support.