Elsunhoty
Elsunhoty

Reputation: 1627

Firebase Rules how to prevent add or update value if its parent is deleted

I am asking about if I had this firebase database

Misters
 + 7m1fyYchDscr8tUeI13uPXvdDvM2
 + gvTVc3gwRfTz3WL48vTGiiiTKZ22
 - vWZ55LGiraaIErIiiVN4NVQc6Eh1
     active_type:true
     age: 27

How to prevent adding new Node or update existing node if its parent is Deleted (vWZ55LGiraaIErIiiVN4NVQc6Eh1)?

For example I have rules that prevent update

{
    "rules": {
        ".read": true,
        ".write": "auth != null",
        "Misters": {
            "$Misterid": {
                "active_type:true": {

                    ".validate": "(data.val() == null) || (data.isString() && (data.val().length == 0))"
                }
            }
        }
    }

But I want to prevent if parent not Found

Upvotes: 3

Views: 772

Answers (3)

Andrey Dobrikov
Andrey Dobrikov

Reputation: 457

Basically what will happen is that your write operation will recreate the deleted "vWZ55LGiraaIErIiiVN4NVQc6Eh1" if I understand correct.

So I would do something like this:

{
    "rules": {
        ".read": true,
    ".write": "auth != null",
    "Misters": {
        ".write" : "root.child('Misters').hasChild(<Misterid>)"
        "$Misterid": {
            "active_type:true": {

                ".validate": "(data.val() == null) || (data.isString() && (data.val().length == 0))"
            }
        }
    }
}

Upvotes: 2

Abhishek
Abhishek

Reputation: 1261

Do you really want to do it in the "rules"? It would mean that you cannot be selective in your application of the logic. I would suggest doing it programmatically.

 DatabaseReference mDatabase = FirebaseDatabase.getInstance();
    rootRef = mDatabase.child("vWZ55LGiraaIErIiiVN4NVQc6Eh1");
    addListenerForSingleValueEvent(new ValueEventListener() {
      @Override
      void onDataChange(DataSnapshot snapshot) {
        if (snapshot.exists()) {
          // run some code here if node exists
        } else { 
            // run some code here if node does not exist
        }
      }
    });

I hope that helps. Doing it this way will mean you can do more than just validation, you can even inform your user and perform UI actions.

Upvotes: 1

J. Doe
J. Doe

Reputation: 13033

  1. Store all the added $Misterid's in a new node called MistersAdded. This can be done automatically by using a cloud function
  2. Add the rule below

This includes a exists() method which will check in the MistersAdded map to see if it has ever been created. If you want to be able to let the user remove the map, add '|| data.val() == null' behind the write rule.

{
    "rules": {
        ".read": true,
        ".write": "auth != null",
        "Misters": {
            "$Misterid": {
                "active_type:true": {
                    ".write": !root.child('MistersAdded').child($Misterid).exists()
                    ".validate": "(data.val() == null) || (data.isString() && (data.val().length == 0))"
                }
            }
        }
    }

Upvotes: 2

Related Questions