Firebase data structure
{root}
dev :
users :
key : userObj
uid : key,
uuidc : auth.uid of this user
key : userObj
key : userObj...
students :
key : studentObj
id : key,
uid: key of user/creator,
uuidc: auth.uid of user/creator (not student),
key : studentObj
key : studentObj...
Firebase rules : accessing student records pass when using the simulator in the firebase console
{
"rules": {
"dev": {
"users": {
".indexOn": [
"uid",
"uuidc"
]
},
"students": {
"$id": {
".read": "data.child($id).child('uuidc').val() == auth.uid",
".write": "data.child($id).child('uuidc').val() == auth.uid",
},
".indexOn": [
"id",
"uid",
"uuidc"
]
},
TS
this.afDb.database.ref('dev/students'))
.orderByChild('uid').equalTo(this.user.uid)
.once('value', (snap) => { ... })
I've also tried query rules
".read": "auth.uid != null && query.orderByChild == 'uuidc' && query.equalTo == auth.uid",
And updating my query to
this.afDb.database.ref('dev/students'))
.orderByChild('uuidc').equalTo(auth.uid)
.once('value', (snap) => { ... })
I create a new user like this
let ref = this.afDb.database.ref('dev/users/').push(newUserObj);
ref.update({ uid: ref.key });
I create a new student like this
let ref = this.afDb.database.ref('dev/students/').push(newStudentObj);
ref.update({ id: ref.key, uid: user.uid});
And all my queries are based on the uid.
As part of researching security rules i decided to write a script that would add a 'uuidc' prop to all objects. This prop holds the auth.uid of the object creator.
When i add the above security rules and run my app, attempting to load all student records associated with a given user fails with the following error
core.js:1448 ERROR Error: permission_denied at /dev/students: Client doesn't have permission to access the desired data.
at Object.exports.errorForServerCode (util.js:513)
at onComplete (SyncTree.js:538)
at Object.eval [as onComplete] (Repo.js:115)
at eval (PersistentConnection.js:189)
at PersistentConnection.onDataMessage_ (PersistentConnection.js:444)
at Connection.onDataMessage_ (Connection.js:262)
at Connection.onPrimaryMessageReceived_ (Connection.js:256)
at WebSocketConnection.eval [as onMessage] (Connection.js:157)
at WebSocketConnection.appendFrame_ (WebSocketConnection.js:197)
at WebSocketConnection.handleIncomingFrame (WebSocketConnection.js:247)
Any help is greatly appreciated!
node 6.11.0
"@angular/core": "5.2.9",
"angularfire2": "^5.0.0-rc.5-next",
"firebase": "^4.8.0",