当前位置: 首页 > 面试题库 >

如何在Firebase中防止重复的用户属性?

皇甫飞宇
2023-03-14
问题内容

我正在FirebaseSimpleLogin用来创建用户并处理身份验证。

当我尝试通过$createUser()方法通过简单登录创建新用户时,如果已经使用了电子邮件地址,firebase不会创建该用户。但是,在$set()创建用户并将其user.uid用作密钥之后,我还用于将创建的用户保存到我的Firebase中。尝试写入数据库时​​,即使用户名不是唯一的,firebase也会保存记录,因为简单登录只需要电子邮件和密码。因此,当用户名不用作用户对象的密钥时,如何验证其唯一性?

我正在这样创建新用户:

$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

但是,既然这不是您的问题,那么让我们在此解决一下,因为您可能想继续前进,并进入我曾多次经历过的双重身份这一棘手的双重身份。

要使用户名唯一,请存储用户名索引。

/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"
        }
     },
  }
}


 类似资料:
  • 这是我的用户注册数据库的方式,但我的问题是:如何防止数据库具有相同用户名的副本,或者换句话说,如果用户名存在于数据库。

  • 是的,在你告诉我将用户名列设置为主键之前,所以不允许重复。我已经在为我的user_id使用主键,它是自动增量的。我希望能够在PHP中进行检查,看看用户名是否已经被取走,并将json_encode发送回我的应用程序。顺便说一句,数据库是托管在线,所以不是真的localhost! 这是我现在使用的,不起作用: 当我运行这个的托管链接时,我得到,但它应该是false:

  • 我一直在做一个登录/注册系统,我正在接近完成我的注册部分代码。我遇到的唯一问题是如何使它使用户不能用重复的用户名注册。我想让它工作,使我的数据库不会接受信息,它会告诉用户有关错误。 我的PHP

  • 问题内容: 我发现指定的角度指令会将指令用法中的属性复制到模板呈现的输出中。如果模板包含相同的属性,则模板属性值和指令属性值将在最终输出中组合在一起。 指令用法: 指示: 输出: 中的空格和中的多个值一样会引起问题。有没有办法改变这种行为?我意识到我可以在指令中使用非冲突属性,并在输出中同时包含模板属性和非冲突属性。但我希望能够使用相同的属性名称,并更好地控制模板的输出。 我想我可以使用方法与和。

  • 问题内容: 我想创建一个表来存储设备设置。该表具有三行:id,parameter_name和parameter_value。 该表是通过执行以下查询语句创建的: 然后通过执行以下方法存储行: 创建数据库后,将存储默认值: 但是,方法insertRow()的问题在于它无法防止重复输入。 有谁知道在这种情况下如何防止重复输入? 问题答案: 您可以使用列约束。 UNIQUE约束导致在指定列上创建唯一索引

  • 问题内容: 我正在尝试保存要分析的歌曲信息,但是如果该歌曲已经存在于分析中,我希望我的代码什么也不做。 我在下面尝试过此代码: 上面的代码在日志中给出以下结果: 成功取得4分。歌曲已存在成功检索到4个乐谱。歌曲已存在成功检索到4个乐谱。歌曲已存在成功检索到4个乐谱。歌曲已存在成功成功成功成功成功成功成功成功成功成功成功成功 为什么我的for循环比Objects.count循环更多?以及如何防止解析