I have a node "purchasetokens" - "$userId" - ""$purchaseToken"" and a key "valid:True/False" that is set by my cloud function only. How can I set a rule to make sure that the "$purchaseToken" doesn't exists across all "$userId" with a "valid:True" key?
"purchasetokens": {
".read": false,
"$userId": {
"$purchaseToken": {
".write": "auth !== null && <<!data.exists() with "valid:True" key across all $userId nodes>>",
"valid": { # this key can only be modified from the cloud function
".write": false,
},
There is no way to search across nodes in security rules. The only thing you can do is read from a known path or check if a known path exists.
That's why you'll have to reframe your use-case to fit those product limitations. Since you want to check if a certain valid token exists, you should either store an (additional) list of valid tokens or a list of tokens with their validity.
An example of the former is this global list of all valid tokens:
validTokens: {
"purchaseToken1": true,
"purchaseToken2": true
}
The true
value in the above is just a dummy value and has no meaning, but you could decide to make it meaningful and for example use true
for valid tokens and false
for invalid ones.
With the above data structure in place you can then check in your rules with:
".write": "root.child('validTokens').child($purchaseToken).exists()"
If you decide to use true
/false
values to indicate validity, the check would become:
".write": "root.child('validTokens').child($purchaseToken).val() === true"