'Firebase Realtime Database prevent delete - based on condition

I would like to prevent deletion of data in Firebase Realtime Database based on a condition. A user that is not author should be able to update the "note", but not delete it.

I have a collection of "notes" in my database that has the following rule set.

"notes": {
  ".read": "
    auth.uid !== null //&&
  ",
  "$note_id": {
    ".write": "
      //New data
      !data.exists() && auth.uid !== null ||
      //Existing data
      data.child('access').child('author').val() === auth.uid ||
      data.child('access/members').child(auth.uid).exists()          
    ",
    "data": { .. },
    "access": {
      "author" : { .. },
      "members" : { .. }
    }
  }
}

How can I only allow "author" to delete the "note"?

I have tried using Google Cloud Functions for Firebase, but only have access to the .onDelete() event which is run after delete is already performed. Could I use the .onWrite() for this purpose - and if so how? I have already implemented listeners for .onCreate() .onUpdate() and .onDelete() for the /notes node in the database.



Solution 1:[1]

It's not possible to use Cloud Functions to intercept incoming requests before they affect the database. As you've seen, they are only used for post-processing.

If security rules are not sufficient to control access the way you want, consider routing the request through an HTTP type Cloud Function that checks permissions, then performs the delete or rejects the request.

Solution 2:[2]

I guess some Firebase rules along the lines

".write" : "
  //Create
  !data.exists() && auth.uid !== null
  //Update
  ||(data.exists() && newData.exists() && data.child('access').child('author').val() === auth.uid || data.child('access/members').child(auth.uid).exists())
  //Delete
  ||(data.exists() && !newData.exists() && data.child('access').child('author').val() === auth.uid)
"

would prevent delete if the user is not author?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Doug Stevenson
Solution 2