1

I have these Firestore Security Rules. I need to check if the 3 amounts "redAmount", "greenAmount" and "blackAmount" added together exceed the user's balance. If so, the update should be rejected.

function checkSums() {
    return futureDocument().redAmount +  futureDocument().blackAmount + 
    futureDocument().blackAmount <= getUserDoc().amount;
}

But this functions fails if one of the amounts is undefined => not set, which I want to be 0, but I can't. Any ideas on how to fix this?

This problem is not solved by referencing to the "How to validate that a field is undefined" question.

filip
  • 628
  • 2
  • 8
  • 31
  • 1
    It seems the `in` operator is best for that. See https://stackoverflow.com/questions/53458413/firestore-security-rules-how-to-validate-that-a-field-is-undefined So something like `(redAmount in futureDocument() ? futureDocument().redAmount : 0)`. – Frank van Puffelen Feb 19 '19 at 14:35
  • Line 16: Unexpected 'futureDocument'. @FrankvanPuffelen I don't think that there is a ? operator if there is no "if" operator. I've looked all over the docs. I've been using the 'in' operator before but you have to combine it with an if. – filip Feb 19 '19 at 14:38
  • Could you please not mark the question as duplicate? @Frank – filip Feb 20 '19 at 12:00
  • 1
    Hmmm.... in that case I'm not sure if the use-case is possible without having a default value for the amount in each document (so: `"redAmount": 0`). – Frank van Puffelen Feb 20 '19 at 15:12
  • Yea at the end I also did this. @FrankvanPuffelen – filip Feb 20 '19 at 15:14

1 Answers1

1

Fixed this with a really insane long workaround (instead of using functions, use or's)

return checkMinusAmount('redAmount') && checkMinusAmount('blackAmount')
                   && checkMinusAmount('greenAmount') && (
                    (futureDocument().redAmount + futureDocument().blackAmount + futureDocument().greenAmount <= getUserDoc().amount) 
                    (futureDocument().redAmount + futureDocument().blackAmount <= getUserDoc().amount  !has('greenAmount')) 
                    (futureDocument().redAmount + futureDocument().greenAmount <= getUserDoc().amount  !has('blackAmount')) 
                    (futureDocument().greenAmount + futureDocument().blackAmount <= getUserDoc().amount  !has('redAmount')) 
                    (futureDocument().greenAmount <= getUserDoc().amount  (!has('redAmount') && !has('blackAmount'))) 
                    (futureDocument().blackAmount <= getUserDoc().amount  (!has('redAmount') && !has('greenAmount'))) 
                    (futureDocument().redAmount <= getUserDoc().amount  (!has('blackAmount') && !has('greenAmount')))
                   )
    }

I ended up not using it and just creating the document with a cloud function and not giving an user the rights to delete it.

filip
  • 628
  • 2
  • 8
  • 31