Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase database rules allow update but prevent create

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:[email protected],
      status:active
    },
    -randomID002:{
      email:[email protected],
      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.

like image 269
Jerry Avatar asked Oct 24 '18 16:10

Jerry


People also ask

How do you edit Realtime Database rules in Firebase?

Edit and update your rulesOpen the Firebase console and select your project. Then, select Realtime Database, Cloud Firestore or Storage from the product navigation, then click Rules to navigate to the Rules editor. Edit your rules directly in the editor.

How do I fix insecure rules in Firebase?

Solution: Rules that restrict read and write access. Build rules that make sense for your data hierarchy. One of the common solutions to this insecurity is user-based security with Firebase Authentication. Learn more about authenticating users with rules.

What is locked mode in Firebase?

Default rules: Locked mode When you create a database or storage instance in the Firebase console, you choose whether your Firebase Security Rules restrict access to your data (Locked mode) or allow anyone access (Test mode).

How do you secure a Firebase Realtime Database without authentication?

If you want to secure data access without requiring the user to sign in with their credentials, consider using Firebase's anonymous authentication. With this provider, you can sign in a user with just this single line of code: FirebaseAuth. getInstance().


2 Answers

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()"
    }
like image 60
abhishek kasana Avatar answered Oct 28 '22 15:10

abhishek kasana


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:[email protected],
      status:active
    },
    -randomID002:{
      email:[email protected],
      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

like image 45
John Avatar answered Oct 28 '22 14:10

John