I Have a Google Firestore realtime database, which contains a flag isPublic
. If set to true
, the child node details
can be read by unauthenticated users. If set to false
, the record can only be accessed by one (for now) authenticated & authorized user.
The authorized user is the only one with write permission.
Further, the child node private
always only grants access to the one authorized user.
The solution I have looked into is based on query based rules https://firebase.google.com/docs/database/security/securing-data#query-based_rules
Unfortunately, I am getting a permission_denied
response, even as the authorized user.
Info aside: this is in a Vue JS project using the Firebase SDK.
Here is my database sample.
The first product should have read access to details
for unauthenticated users, but not to private
.
The second one should not be shown to unauthenticated users at all, by forcing them to run the query dbRef.orderByChild('isPublic').equalTo(true)
"products": {
"-pushIdxyz1" : {
"isPublic" : true,
"private" : {
"notes" : "lorem ipsum always private",
"soldDate" : ""
},
"details" : {
"imageURL" : "https://firebasestorage.imagexyz",
"keywords" : "this, that",
"title" : "Public product title",
"workCategory" : "hardware",
},
},
"-pushIdxyz2" : {
"isPublic" : false,
"private" : {
"notes" : "lorem ipsum always private",
"soldDate" : ""
},
"details" : {
"imageURL" : "https://firebasestorage.imagexyz",
"keywords" : "this, that",
"title" : "Secret product title",
"workCategory" : "hardware",
},
}
}
And my not-working rules
"rules": {
"products": {
"$product_id": {
".indexOn": "isPublic",
".read": "query.equalTo == true || auth.uid == '[admin user id]'"
// alternative attempt
// ".read": "(query.orderByChild == 'isPublic' && query.equalTo == true) || auth.uid == '[admin user id]'",
,
".write": "auth.uid == '[admin user id]'",
"details": {
".read": true,
},
"private": {
".read": "auth.uid == '[admin user id]'",
}
}
}
}
This query, for unauthorized users, should give read access to the details child node:
firebase.database().ref('products').orderByChild('isPublic').equalTo(true).once('value')
.then(...)
This query, for the authorized user only, should give read access to all data
firebase.database().ref('products').once('value')
.then(...)
With the current setting I am getting "permission denied" for either query, logged in as the authorized user or not.