Reputation: 103
I have user associated with each data,
and rule defines as below-
{
"rules": {
".read": false,
".write": false,
"expenses": {
".read": "auth.uid === data.child('userId').val()",
".write": "auth.uid === data.child('userId').val()"
},
"categories": {
".read": "auth != null",
".write": "auth != null"
}
}
}
I have a requirement that the user can only read the data where their userId is associated.
function to get Data-
getExpense():AngularFireList<ExpenseData>{
if (!this.userId) return;
this.expenses = this.db.list(`expenses`);
return this.expenses
}
getCategory():AngularFireList<CategoryData>{
if (!this.userId) return;
this.categories = this.db.list('categories');
return this.categories;
}
Error:
ERROR Error: permission_denied at /expenses: Client doesn't have permission to access the desired data.
Upvotes: 0
Views: 1474
Reputation: 598728
It looks like you're trying to read from /expenses
, but this is the condition to get access to /expenses
:
".read": "auth.uid === data.child('userId').val()",
Since there is no /expenses/userId
, nobody has access to /expenses
. If you add a /expenses/userId
with a UID, then the user with that UID will have access to all of /expenses
, not just their own.
Note that security rules can't be used to filter data, which I think you're trying to do. This topic has been covered a lot before, so I recommend you check out a few of the questions that mention "rules are not filters".
Since a few months it is possible to accomplish your scenario. But you will need to do this as two steps that go hand-in-hand:
See the documentation on query-based rules. From there:
The code:
db.ref("baskets").orderByChild("owner") .equalTo(auth.currentUser.uid) .on("value", cb)
The rules:
"baskets": { ".read": "auth.uid != null && query.orderByChild == 'owner' && query.equalTo == auth.uid" // restrict basket access to owner of basket }
Upvotes: 2