简体   繁体   English

Firebase查询唯一的用户名swift

[英]Firebase querying for unique Username swift

I searched for this question, but none of them had an answer that worked for me. 我搜索了这个问题,但他们都没有一个对我有用的答案。

I want to make it so when a user registers an account, it checks to see if the username they have entered already exists, before creating the account. 我想在用户注册帐户时这样做,它会在创建帐户之前检查他们输入的用户名是否已经存在。 I have tried using querying in firebase, but I just can't seem to get it to work. 我曾尝试在firebase中使用查询,但我似乎无法让它工作。

Here is an image of what my firebase data looks like: My firebase data tree 这是我的firebase数据的图像: 我的firebase数据树

How would I use query to find the string for the key "username"? 我如何使用查询来查找密钥“用户名”的字符串?

You can go like this, make one function with completion block to check username is already exist in your Firebase DB and create new user on the basis of it 您可以这样,使用完成块创建一个功能以检查您的Firebase数据库中是否已存在用户名,并在此基础上创建新用户

func checkUserNameAlreadyExist(newUserName: String, completion: @escaping(Bool) -> Void) {

    let ref = FIRDatabase.database().reference()
    ref.child("users").queryOrdered(byChild: "username").queryEqual(toValue: newUserName)
              .observeSingleEvent(of: .value, with: {(snapshot: FIRDataSnapshot) in

        if snapshot.exists() {
            completion(true)
        }
        else {
            completion(false)
        }
    })
}

Now simply call this function when you create new user: 现在只需在创建新用户时调用此函数:

self.checkUserNameAlreadyExist(newUserName: "Johnson") { isExist in
    if isExist {
        print("Username exist")
    }
    else {
        print("create new user")
    }
}

This is how I do it: 我是这样做的:

var text = "Your username"

let dbRef = FIRDatabase.database().reference().child("users")
dbRef.queryOrdered(byChild: "name").queryEqual(toValue: text).observeSingleEvent(of: .value, with: { snapshot in
    if !snapshot.exists() {
         // Name doesn't exist
    }

    if let data = snapshot.value as? [String: [String: String]] {
         // it should exist if it reaches here
    }
})

Make sure in your database rules to index the "users" node on "name" for performance optimization. 确保在数据库规则中索引“name”上的“users”节点以进行性能优化。

I do this next way: 我接下来这样做:

The function of register: 注册功能:

@IBAction func signUpButtonTapped(_ sender: Any) {
  User.getItemByLogin(for: userLogin.text!,
                      completion: { userItem in
                       if userItem == nil {
                          self.createAndLogin()
                       } else {
                          self.showAlertThatLoginAlreadyExists()
                       }
  })
}


private func createAndLogin() {
  FIRAuth.auth()!.createUser(withEmail: userEmail.text!,
                             password: userPassword.text!) { user, error in
                                if error == nil {
                                   // log in
                                   FIRAuth.auth()!.signIn(withEmail: self.userEmail.text!,
                                                          password: self.userPassword.text!,
                                                          completion: { result in
                                                           // create new user in database, not in FIRAuth
                                                           User.create(with: self.userLogin.text!)

                                                           self.performSegue(withIdentifier: "fromRegistrationToTabBar", sender: self)
                                   })
                                } else {
                                   print("\(String(describing: error?.localizedDescription))")
                                }
}

private func showAlertThatLoginAlreadyExists() {
  let alert = UIAlertController(title: "Registration failed!",
                                message: "Login already exists.",
                                preferredStyle: .alert)

  alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))

  present(alert, animated: true, completion: nil)
}

My User class function. 我的用户类功能。 It's API like class: 它的类似API:

static func getItemByLogin(for userLogin: String,
                          completion: @escaping (_ userItem: UserItem?) -> Void) {
  refToUsersNode.observeSingleEvent(of: .value, with: { snapshot in

     for user in snapshot.children {
        let snapshotValue = (user as! FIRDataSnapshot).value as! [String: AnyObject]
        let login = snapshotValue["login"] as! String // getting login of user

        if login == userLogin {
           let userItem = UserItem(snapshot: user as! FIRDataSnapshot)
           completion(userItem)
           return
        }
     }

     completion(nil) // haven't founded user
  })
}

In your way you should swap login with username . 在你的方式你应该用username交换login

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM