9

How to set the database rules with "allow to update but not allow to add new record"?

I tried to simulate below but doesn't work..

My Data:

{
  users:{
    -randomID001:{
      email:user@email.com,
      status:active
    },
    -randomID002:{
      email:user2@email.com,
      status:inactive
    }
  }
}

Simulate in the console:

{
  "rules": {
    ".read": "auth != null",
    "users":{
      ".indexOn": "email",
      ".write":"!newData.exists() && data.exists()" 
    }
  }
}

This line of code show mean for allow to write if new record doesn't exist and existing record exist ??

".write":"!newData.exists() && data.exists()" 

Below is the test data i submit:

{
  "randomID001":{"status":"inactive"}
}

I got the below error:

Simulated update denied

Please advise.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Jerry
  • 1,455
  • 1
  • 18
  • 39

2 Answers2

9

You can use validate to check if email already exists in the database this will allow only update on the existing users.

"users":{
    "$userId":{
      ".write":"auth!=null",
      ".validate":"newData.child('email').val()===data.child('email').val()"
    }
abhishek kasana
  • 1,462
  • 12
  • 14
2

Firebase Realtime Database Simulator allows you to test [READ, SET, UPDATE]

It looks like dealing with firebase object.

FIREBASE DB MODEL - here is yours

{
  users:{
    -randomID001:{
      email:user@email.com,
      status:active
    },
    -randomID002:{
      email:user2@email.com,
      status:inactive
    }
  }
}

Try with different Locations

/users/randomID001  //  exists in your DB
/users/randomID002  //  exists in your DB
/users/randomID003  //  not exists in your DB

CREATE

// newData(json) exists and no randomID001,002 data => FALSE
// newData(json) exists and no randomID003 data => TRUE
".write": "newData.exists() && !data.exists()" 

UPDATE

// newData(json) exists and target(randomID001,002) data exists => TRUE
// newData(json) exists and target(randomID003) data exists => FALSE
".write": "newData.exists() && data.exists()"

DELETE

//You are sending only HTTP DELETE SIGNAL, NOT JSON
//Target(randomID001,002) data exists => TRUE
//Target(randomID003) data exists => FALSE
".write":"!newData.exists() && data.exists()"

next example is allowing [create,update] You can think like "CREATE || UPDATE || DELETE".

{
  "rules": { 
    "users": {
      "$uid":{
        ".write": "(newData.exists() && !data.exists()) || (newData.exists() && data.exists())"
      }
    }
  }
}

Also validation rule is good idea to be secured.

VALIDATION

...
items: {
    "$itemId": {
      ".validate": "newData.hasChildren(['name', 'message', 'timestamp'])",
      "name": {
        ".validate": "newData.val().length > 0 && newData.val().length < 20"
      },
      "message": {
        ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 50"
      },
      "timestamp": {
        ".validate": "newData.isNumber() && newData.val() == now"
      }
}
...

For your code maintenance, Firebase bolt is good choice. https://github.com/firebase/bolt/blob/master/docs/language.md

John
  • 3,304
  • 1
  • 18
  • 26