Firebase security rule and check for unique records

[亡魂溺海] 提交于 2019-12-10 10:49:49

问题


I'm building an AngularjS app that allows users (authenticated with Firebase anonymous) to submit their Fullname, Company and Email address to get on our distribution list.

What I want to accomplish is to disable the users form entering data twice, hence checking if the data submitted already exists in the database. When it does, it should deny the submitted data, keeping my DB clean. The UI will take care of all the error messages and so on.

My endpoint: http://someurl.firebaseio.com/accounts/

Sample data submitted to /accounts/ via push() :

{fullName: "John Doe", company: "Pet's Place", email: "john@petsplace.org"}

Firebase security rules setup:

Goal: Everybody may write to /accounts/ to register, only unique values and with validations for length and isString. Reading is not allowed for the anonymous users.

{
"rules": {
    ".read": "auth !== null",
    ".write": "auth !== null",
    "accounts": {
        ".write": "auth !== null && newData.exists()",
        "$accountID": {
            ".read": false,
            ".validate": "newData.hasChildren(['fullName', 'company', 'email'])",
            "fullName": {
                ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 50 && !newData.val().contains('admin')"
            },
            "company": {
                ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 50"
            },
            "email": {
                ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 50"
            }
        }
    }
}
}

The result after (multiple) submit

{
"accounts" : {
"-JY249g70KL-XG0c6ekM" : {
  "company" : "Pet's Place",
  "email" : "john@petsplace.org",
  "fullName" : "John Doe"
},
"-JY249y2IwFWAYwEqC4Q" : {
  "company" : "Pet's Place",
  "email" : "john@petsplace.org",
  "fullName" : "John Doe"
},
"-JY24ACApcPH2_jiU5PD" : {
  "company" : "Pet's Place",
  "email" : "john@petsplace.org",
  "fullName" : "John Doe"
},
"-JY24AL8QOKQRiTh3Oqm" : {
  "company" : "Pet's Place",
  "email" : "john@petsplace.org",
  "fullName" : "John Doe"
}
}
}

回答1:


By using the email address as a key, you can make sure there will be only one entry for each email address:

var fbRef = new Firebase('https://someurl.firebaseio.com/');

// create a new user somehow
var newUser = {
    fullName: "John Doe", 
    company: "Pet's Place", 
    email: "john@petsplace.org"
}

// escape '.' because it can not be used as a key in FB
function escapeEmail(email){
    return email.replace(/\./g, ',');
}

fbRef.child('accounts').child(escapeEmail(newUser.email)).set(newUser, function(err) {
    if(err) {
        // if there was an error, the email address already exists
    }
);

Then in your rules validate that the key (email address) does not already exist:

{
    "rules": {
        ".read": true,
        "accounts": {
            "$account": {
                ".write": true,
                ".validate": "!root.child('accounts').child(newData.child('email').val().replace(/\./g, ',')).exists()"
            }
        }
    }
}

Also have a look here for some additional information: What Firebase rule will prevent duplicates in a collection based on other fields? and here: How do you prevent duplicate user properties in Firebase?



来源:https://stackoverflow.com/questions/26108341/firebase-security-rule-and-check-for-unique-records

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!