What is the actual correct condition to use in the Firestore rules to restrict access to only authenticated users? The official docs and several answers here say that you should use request.auth.uid != null
. I've used this in the past and it seemed to work, but recently when I was testing some other rules in the simulator I noticed that it throws a Null value error
on that condition when the request is unauthenticated.
If that is the case, it seems that request.auth != null
is the actual condition you should use, as it appears to behave as intended in the simulator.
Is this a discrepancy between the simulator and the actual behavior of the rules? If the simulator is correct, I assume the request.auth.uid != null
condition only "works" because the default behavior is to deny access if there is an error in a condition. The other option is that the simulator is wrong and request.auth
is never null
when actually using the database.
Which is it?
I did some testing with a few different conditions and found that my hypothesis appears to be correct -- the request.auth.uid != null
condition is "working" because it throws an error when the user is unauthenticated. This probably doesn't cause any problems in most scenarios since you would likely want to deny access anyway; however, it does cause a problem if you try to write the inverse condition request.auth.uid == null
. Since that throws an error when unauthenticated, it will also cause a rule to deny access.
My conclusion is that the docs are technically incorrect and the condition that should be used to check if the user is authenticated is request.auth != null
. You can see the results of my tests below, with the incorrect behavior in bold.
Access restriction as described by the docs:
allow read, write: if (request.auth.uid != null);
Alternate access restriction:
allow read, write: if (request.auth != null);
Inverse restriction (docs condition):
allow read, write: if (request.auth.uid == null);
Inverse restriction (alternate condition):
allow read, write: if (request.auth == null);