我正在FirebaseSimpleLogin用来创建用户并处理身份验证。
FirebaseSimpleLogin
当我尝试通过$createUser()方法通过简单登录创建新用户时,如果已经使用了电子邮件地址,firebase不会创建该用户。但是,在$set()创建用户并将其user.uid用作密钥之后,我还用于将创建的用户保存到我的Firebase中。尝试写入数据库时,即使用户名不是唯一的,firebase也会保存记录,因为简单登录只需要电子邮件和密码。因此,当用户名不用作用户对象的密钥时,如何验证其唯一性?
$createUser()
$set()
user.uid
我正在这样创建新用户:
$scope.createUser = function() { $scope.auth.$createUser('trinker@gmail.com', 'password').then(function(user, err) { if (!err) { ref.child('users/' + user.uid).set({ email: user.email, username: user.username }); console.log("success!"); }else{ console.log(err.message); } }); }
我的用户对象如下所示:
{ "users" : { "simplelogin:28" : { "email" : "trinker@gmail.com", "username" : "jtrinker" }, "simplelogin:30" : { "email" : "test@gmail.com", "username" : "jtrinker" } } } }
我需要使用uid作为每个用户的密钥,但是我仍然需要用户名唯一。
如果一个对象内的属性不是另一个对象内的属性所独有,如何防止Firebase保存记录?
首先,如果用户已经有一个username,它是唯一的,并且不会消失,我建议您放弃使用简单的login uid。正如您已经在此处发现的那样,这只会产生试图在两者之间来回切换的问题,而不会产生任何其他结果。研究使用firebase-passport- login之类的工具创建自己的令牌,然后通过来存储记录。username
username
uid
但是,既然这不是您的问题,那么让我们在此解决一下,因为您可能想继续前进,并进入我曾多次经历过的双重身份这一棘手的双重身份。
要使用户名唯一,请存储用户名索引。
/users/$userid/username/$username /usernames/$username/$userid
为了确保它们是唯一的,请在用户名/路径中的用户标识上添加如下安全规则,以确保每个用户名只能分配一个用户,并且该值是该用户的标识:
".write": "newData.val() === auth.uid && !data.exists()"
现在,通过将以下内容添加到用户/记录中的用户名来强制它们匹配:
"users": { "$userid": { "username": { ".validate": "root.child('usernames/'+newData.val()).val() === $userid" } } }
这将确保ID是唯一的。注意读取权限。您可能希望完全避免这种情况,因为您不希望任何人查找私人电子邮件或用户名。像我展示的支持节省这些的东西将是理想的。
这里的想法是您尝试分配用户名和电子邮件,如果它们失败,则它们已经存在并属于另一个用户。否则,您可以将它们插入用户记录中,然后让用户通过uid和email进行索引。
为了符合SO协议,以下是该要点的代码,最好通过链接阅读:
var fb = new Firebase(URL); function escapeEmail(email) { return email.replace('.', ','); } function claimEmail(userId, email, next) { fb.child('email_lookup').child(escapeEmail(email)).set(userId, function(err) { if( err ) { throw new Error('email already taken'); } next(); }); } function claimUsername(userId, username, next) { fb.child('username_lookup').child(username).set(userId, function(err) { if( err ) { throw new Error('username already taken'); } next(); }); } function createUser(userId, data) { claimEmail(userId, data.email, claimUsername.bind(null, userId, data.username, function() { fb.child('users').child(userId).set(data); ); }
和规则:
{ "rules": { "users": { "$user": { "username": { ".validate": "root.child('username_lookup/'+newData.val()).val() === auth.uid" }, "email": { ".validate": "root.child('email_lookup').child(newData.val().replace('.', ',')).val() === auth.uid" } } }, "email_lookup": { "$email": { // not readable, cannot get a list of emails! // can only write if this email is not already in the db ".write": "!data.exists()", // can only write my own uid into this index ".validate": "newData.val() === auth.uid" } }, "username_lookup": { "$username": { // not readable, cannot get a list of usernames! // can only write if this username is not already in the db ".write": "!data.exists()", // can only write my own uid into this index ".validate": "newData.val() === auth.uid" } }, } }