2016-04-14 80 views
0

我有一个小用户登录表单,其中新用户必须添加他的用户名,密码和昵称(因为基本的firebase auth只接受电子邮件作为用户名,对吧? )。在创建用户之前检查Firebase上是否存在数据

这是一个用户结构在我火力地堡创建接收绰号enter image description here

的关键是基于用户名和它有2个孩子:昵称和用户名。

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

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

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

有没有另一种方法(更好的方法)来做到这一点?

该方法如下。 谢谢!

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) 

      }) 
     } 


    }) 
} 
+1

不再需要这个问题了,但总的来说:请记住,问题中的JSON树的图片几乎不像JSON那样有用,因为您可以通过单击“导出”按钮您的Firebase数据库。将JSON作为文本可以搜索,使我们能够轻松使用它来测试您的实际数据,并将其用于我们的答案中,并且通常只是一件好事。 –

回答

3

我在构建最新的Firebase应用程序时遇到了同样的问题。我用来解决它的方法是从用户名到用户ID创建一个额外的映射。所以,我的结构看起来就像这样(uid是从火力地堡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,因此您可以使用用户名和密码登录用户。
+0

哇!好主意啊!我会在这里尝试。我一定会试一试。 谢谢! –

+0

@LucasAlmeida很高兴听到! – pkacprzak

+0

它会一定会派上用场,使auth过程更好(使用昵称而不是电子邮件),但对于firebase-swift问题,我需要弄清楚是否我会保持当前的方式或不。 由于observeSingleEventOfType行为异步,所以在它的block执行之前它正在执行createUser,并且对于一个存在的昵称返回true的变量被发送为false,所以多个用户使用相同的昵称创建。这就是为什么我'夹着'viewSingleEventOfType块内的createUser代码... –

0

刚抬起头的同步问题,我与火力地堡事件观察:

昨天,我还以为是工作,调用SEGUE打开另一个的viewController,当我有问题(它被调用新的观点,而观察员仍然运行没有结果和应用程序崩溃,因为委托方法正在使用未声明在其他视图)...

作为解决方案,我摆脱了所有代表,并重新编码使用完成处理程序的方法...现在它真的很好!

呵呵,和@pkacprzak:我做了修改并开始使用这个'桥梁结构'来存储昵称和uid之间的关系。男人,现在踢它!非常感谢你!

+0

太棒了!说到完成处理程序,如果有人知道他们的力量,那么在链接异步任务时有这样一个很棒的概念:)并且你使用它们 – pkacprzak

相关问题