Simon H Simon H - 23 days ago 7
TypeScript Question

Firebase: prevent all but .push to a list

I have read In firebase, can I set permissions to allow only PUSH operations to a given object? and so far copied it, but it does not work.

I have a site that is used anonymously, and where I collect comments. I want to store new ones to be added, but to prevent editing and deleting of existing data.

Angular 2, with AngularFire2

export class FirebaseService {

comments: FirebaseListObservable<Object>;
locations: FirebaseListObservable<Object>;

constructor(private af: AngularFire) {
this.comments = this.af.database.list(environment.stem + '/comments');
}

addComment(comment) {
return this.comments.push(comment)
.catch(err => console.error(err));
}
}


I expected this rule would do it as there will be no existing data in the case that I push?

{
"rules": {
".read": true,
".write": "!data.exists()"
}
}


Setting the write rule to
true
makes it work but looser than I want.

Here are the beginnings of the existing json in this route of the database (the keys here come from a service I am migrating away from)

{
"0763a8d3e2407697" : {
"comment" : "Thanks for your comments and feedback, Simon",
"date" : "Sat Jan 03 2015 08:46:17 GMT+0100 (CET)"
},...

Answer

With your current rules, the database server will reject the write whenever any data exists in the database.

But your use-case seems to only want to reject write that overwrite a specific existing comment. For that use-case, you should put the .write rule lower into the tree:

{
  "rules": {
    ".read": true,
    "$stemid": {
      "comments": {
        "$commentid": {
          ".write": "!data.exists() && newData.exists()"
        }
      }
    }
  }
}

These rules use $ variables to ensure they apply across all stems and all comments.