【问题标题】:Checking if data exists on Firebase before creating User在创建用户之前检查 Firebase 上是否存在数据
【发布时间】:2016-08-06 18:24:25
【问题描述】:

我有一个小的用户登录表单,新用户必须在其中添加他的用户名、密码和昵称(因为基本的 firebase 身份验证只接受电子邮件作为用户名,对吗?)。

这是我在 Firebase 上创建的用户结构,用于接收昵称

密钥基于用户名,它有 2 个子项:昵称和用户名。

在尝试使用 Firebase 中的 auth 方法创建用户之前,我会查询以检查昵称是否已经存在。如果是,它不会创建用户并引发警报。如果昵称不存在,它会创建用户,然后将昵称添加到上图中的用户结构中。

有些时间思考和更改代码(代码正在跳转'observeSingleEventOfType'并执行createUser,然后检查昵称是否已经存在),我认为一个好主意是获取createUser代码并添加它直接在昵称查询上的 observeSingleEventOfType 内,作为 'if snapshot.exists()' 的 'else' ...

它似乎正在工作,但我不知道这是否是执行它的“正确”方式......

还有其他方法(更好的方法)吗?

方法如下。 谢谢!

 func createUser(username: String, password: String, nickname: String){

    var userCreated = false
    var errorCode = 0

    users.queryOrderedByChild("Nickname").queryEqualToValue(nickname).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        if snapshot.exists() {
            errorCode = 3
            self.delegate?.didReceiveResponseFromFirebaseCreateUser!(userCreated, errorCode: errorCode)
        }
        else{
            self.ref.createUser(username, password: password, withCompletionBlock: { (error) in
                if error != nil {
                    print (error.description)

                    if error.description.rangeOfString("EMAIL_TAKEN") != nil {
                        errorCode = 1
                    }
                    else if error.description.rangeOfString("INVALID_EMAIL") != nil {
                        errorCode = 2
                    }

                }
                else{
                    userCreated = true
                    let newUser = User(username: username, nickname: nickname)

                    let newUserRef = self.users.childByAppendingPath(username.stringByReplacingOccurrencesOfString(".", withString: "-"))
                    newUserRef.setValue(newUser.toAnyObject())

                }

                self.delegate?.didReceiveResponseFromFirebaseCreateUser!(userCreated, errorCode: errorCode)

            })
        }


    })
}

【问题讨论】:

  • 这个问题不再需要,但总的来说:请记住,您问题中 JSON 树的图片不如将 JSON 作为文本有用,您可以轻松获得单击 Firebase 数据库中的导出按钮。将 JSON 作为文本使其可搜索,让我们可以轻松地使用它来测试您的实际数据并在我们的答案中使用它,一般来说这只是一件好事。

标签: ios swift firebase swift2 firebase-realtime-database


【解决方案1】:

提醒一下我在使用 Firebase 事件观察器时遇到的同步问题:

昨天,我认为它正在工作,我在调用 segue 打开另一个 viewController 时遇到了问题(它正在调用新视图,而 Observer 仍在运行但没有结果,并且应用程序崩溃了,因为委托方法正在使用 is' t 在另一个视图上声明)...

作为解决方案,我摆脱了所有委托并使用完成处理程序重新编码了方法......现在一切顺利!

哦,还有@pkacprzak:我进行了更改并开始使用这个“桥结构”来存储昵称和 uid 之间的关系。伙计,现在它在踢!非常感谢你!

【讨论】:

  • 太棒了!说到完成处理程序,如果有人知道它们的功能,那么在链接异步任务方面会有一个很棒的概念:) 并且你正在使用它们真是太好了
【解决方案2】:

我在构建最后一个 Firebase 应用时遇到了同样的问题。我用来解决它的方法是创建一个从用户名到用户 ID 的附加映射。所以我的结构看起来像这样(uid 是来自 Firebase auth 的用户 id):

users: {
   accounts: {
      uid1: { 
          username: frank,
          ...
      },
      uid2: { 
          username: monique,
          ...
      }
      ...
   },
   username_to_uid: {
      frank: uid1,
      monique: uid2,
      ...
   }
}

这允许两个主要的事情:

  1. 当用户尝试注册时,您可以先使用“username_to_uid”映射检查他提供的用户名是否已经存在
  2. 您也可以使用用户名和密码登录用户。默认情况下,您可以使用 Firebase 身份验证通过电子邮件和密码登录用户。这里的想法是,对于给定的用户名,您可以使用“username_to_uid”映射轻松检索与该用户名关联的 uid,因此您可以使用用户名和密码登录用户。

【讨论】:

  • 哇!好主意啊!我会在这里试试。我一定会试一试的。谢谢!
  • @LucasAlmeida 很高兴听到这个消息!
  • 它肯定会派上用场,使身份验证过程更好(使用昵称而不是电子邮件),但对于 firebase-swift 问题,我需要弄清楚我是否会保留它当前方式与否...由于observeSingleEventOfType的行为是异步的,因此在执行其块之前它正在执行createUser,并且为现有昵称返回true的变量被发送为false,因此使用相同的昵称创建了多个用户.这就是为什么我将 createUser 代码“夹在”observeSingleEventOfType 块内...
  • 我会继续寻找其他选项(尽管它有效)...但我肯定会在我的登录方法中使用您的想法!再次感谢您!
  • 很好的解决方案@pkacprzak。不要忘记用安全规则保护数据,这样任何人都不能覆盖别人的昵称(只有拥有的 uid 才能删除它)。
猜你喜欢
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
相关资源
最近更新 更多