I'm working on a simple app that maintains a transaction ledger.
My data looks like this:
{
"payments": {
"user1": {
"payment1": {
"amount": 2,
"timestamp": 1475303826
}
}
},
"purchases": {
"user1": {
"purchase1": {
"amount": 0.25
"timestamp": 1475303735
},
"purchase2": {
"amount": 1.99
"timestamp": 1475303792
}
}
},
"users": {
"user1": {
"balance": -0.24
}
}
}
Everytime I add a payment, I want the user's balance to increase, and when I add a purchase, I want the balance to decrease.
Is there a way to setup Firebase rules so that a user's balance is always equal to the sum of their purchases and payments?
Edit
Following Frank van Puffelen's answer, I managed to create these rules:
"purchases": {
"$uid": {
"$pid": {
".validate": "!data.exists() && (newData.parent().parent().parent().child('users/'+$uid+'/balance').val() == root.child('users/'+$uid+'/balance').val() - newData.child('amount').val())"
}
}
},
"payments": {
"$uid": {
"$pid": {
".validate": "!data.exists() && (newData.parent().parent().parent().child('users/'+$uid+'/balance').val() == root.child('users/'+$uid+'/balance').val() + newData.child('amount').val())"
}
}
}
These make sure that any new purchase or payment is accompanied by a matching update to the user's balance.
I'm now trying to come up with rules that would prevent changing the balance without adding a purchase or payment. I had the idea to add a rule to a user's balance to verify that, during an update, there was exactly one new purchase or payment, but I don't think there is a way to count a node's children using the rules DSL.