1
votes

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.

1
It seems the in operator is best for that. See stackoverflow.com/questions/53458413/… So something like (redAmount in futureDocument() ? futureDocument().redAmount : 0). - Frank van Puffelen
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
Could you please not mark the question as duplicate? @Frank - filip
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
Yea at the end I also did this. @FrankvanPuffelen - filip

1 Answers

1
votes

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.