I have rules in my database to restrict users to only access data that belongs to their own account id. For debugging purposes, I would like to give all users of our own company access to all other user data.
Something like this works:
match /databases/{database}/documents {
function matchesUserAccountId(accountId) {
return request.auth.token.account_id == accountId ||
request.auth.token.account_id == "our_own_account_id"
}
match /some_collection/{accountId}/{document=**} {
allow read: if matchesUserAccountId(accountId)
}
}
But this would obviously be a bad idea for a production database. So I would like to limit this to only our development database.
However, the following doesn't seem to work:
match /databases/{database}/documents {
function matchesUserAccountId(accountId) {
return request.auth.token.account_id == accountId ||
(database == "our_dev_project_id" && request.auth.token.account_id == "our_own_account_id")
}
match /some_collection/{accountId}/{document=**} {
allow read: if matchesUserAccountId(accountId)
}
}
I'm not sure why the database
variable wouldn't match with the project id. I can't seem to find any info on what it might be instead. I initialize Firebase with:
databaseURL: `https://${process.env.FIREBASE_PROJECT_ID}.firebaseio.com`,
So FIREBASE_PROJECT_ID is what I'm trying to match with. Should I use something else maybe?
CodePudding user response:
Each Firebase project can have only 1 Firestore instance at the moment and the value of {database}
wildcard is (default)
. You cannot get the project ID in security rules but a workaround would be to store the project ID in a document that no one else can update and read that in the rules using get()
function.
Custom Claims might be useful as well. You can set a claim "role" that'll be set in dev project only. So the following rule will pass in that project only:
allow read: if request.auth.uid == userId || hasAdminRoleClaim();
But you'll have to ensure no one can create a user with that role in production project.