skip to Main Content

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,
            }, 

2

Answers


  1. try the following may be this is what you want correctly …

    {
      "rules": {
        "purchasetokens": {
          "$userId": {
            "$purchaseToken": {
              ".write": "!root.child('purchasetokens').child($userId).child($purchaseToken).child('valid').val() === true"
            }
          }
        }
      }
    }
    

    it will checks if the valid key of the specified $purchaseToken under the corresponding $userId is true. If it is true, the write operation will be denied, preventing duplicate purchase tokens with a valid: true key.

    Login or Signup to reply.
  2. 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 check in your rules with:

    ".write": "root.child('validTokens').child($purchaseToken).exists()"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search