Home Firebase Rules Confusion
Reply: 1

Firebase Rules Confusion

askaale
1#
askaale Published in 2016-10-31 01:06:56Z

I am getting very confused with the Firebase rules structure. Basically I have a root folder called 'Transactions', containing many childByAutoIDs that again contains data, exactly like this:

Transactions {
    autoID1 {
        transactionID: whatever,
        timeCreated: whatever,
        "amount": whatever,
        "sender": whatever,
        "receiver:whatever"
    }
}

I am now trying my best to implement the best possible security rules. I therefore tried to do something like this:

"Transactions": {
    ".write": "auth !== null",
    "$transactionAutoID": {
        "timeCreated": {
            ".write": "auth !== null && data.child('sender').val() === auth.uid || data.child('receiver').val() === auth.uid",
            ".read": "auth !== null && data.child('sender').val() === auth.uid || data.child('receiver').val() === auth.uid"
        }
    }
}

So basically, from what I have learned, and also what I am struggling with - is the fact that the user is able to write anything, even in the 'wildcard IDs ($transactionAutoID)'. I know this is because I have set the '.write' in Transactions to 'auth !== null' - but if I don't have this set, users may not read or write any transaction data. (I have the rules by default set to false).

How would I proceed if I only wanted users to be able to create new childs in Transactions, but not write in any transaction keys, if they are not either the sender or the receiver?

Frank van Puffelen
2#
Frank van Puffelen Reply to 2016-10-31 02:43:23Z

Once a permission is granted on a node, it cannot be taken away on a lower-level node.

So if you look at this:

"Transactions": {
    ".write": "auth !== null",
    "$transactionAutoID": {
        "timeCreated": {
            ".write": "auth !== null && data.child('sender').val() === auth.uid || data.child('receiver').val() === auth.uid",
            ".read": "auth !== null && data.child('sender').val() === auth.uid || data.child('receiver').val() === auth.uid"
        }
    }
}

The write rule on Transactions/$transactionId/timeCreated is meaningless, since it tries to tighten the permission from Transactions.

So right now it functions like this:

"Transactions": {
    ".write": "auth !== null",
    "$transactionAutoID": {
        "timeCreated": {
            ".read": "auth !== null && data.child('sender').val() === auth.uid || data.child('receiver').val() === auth.uid"
        }
    }
}

If you want to put a limit to specifically what a user can do on Transactions/$transactionId/timeCreated, you will either have to do so in a validation rule or (more likely) by putting all the rules on the transaction itself:

"Transactions": {
    "$transactionAutoID": {
        ".write": "auth !== null && (
            !data.exists() || (
                newData.child('sender').val() === auth.uid ||
                newData.child('receiver').val() === auth.uid)"
            )
        )"
    }
}

In words: you can write a transaction when you're authenticated and either the transaction doesn't exist yet or you're the sender or receiver of the transaction.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.298248 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO