Firestore Swift 5: Validating if document username data exists

767 Views Asked by At

I'm trying to build a signup view where I am trying to validate if a username value exists in my Firestore database. I have another function that validates my text fields, but I just can't seem to figure out why this function still performs the segue after my conditional statement to validate if the username exists in the database.

Any advice and improvements would be much appreciated as I am new to Swift. :)

    func signUpUser () {

        db.collection("Users").getDocuments { (querySnapshot, error) in
            if let error = error {
                print("Error connecting to database")
            }
            else {
                if let snapshotDocuments = querySnapshot?.documents {
                    for doc in snapshotDocuments {
                        let data = doc.data()
                        if let username = data["username"] as? String{
                            let usernameImput = self.usernameTextField.text



                            if usernameImput == username {

                                print("Username not available")
                            }

                            else if usernameImput != username {

                                let userID = Auth.auth().currentUser!.uid

                                if let name = self.nameField.text, let email = self.emailTextField.text, let username = self.usernameTextField.text {
                                    self.db.collection("Users").document("\(userID)").setData(["name":name,"email":email, "username":username, "accountBalance": 0]) { (error) in

                                        if error != nil {
                                            // MARK: ERROR POPUP
                                            print("Error saving data")
                                        }



                                        else {

                                            self.performSegue(withIdentifier: "signedUp", sender: self)

                                        }

                                    }
                                }


                                print("Sign Up Successfully.")

                            }

                            else {
                                print("Other problems")
                            }
                        }
                    }

                }
            }

        }



    }

Thank you so much in advance for any help or contributions. :D

1

There are 1 best solutions below

1
On BEST ANSWER

Your code:

  1. Loads all user documents
  2. Loops over these documents
  3. Writes a new document for this user if it finds any document with a different name

So as soon as there's any user who has a different name than the one you're trying to add, you add a document for the user. It seems your use-case is to only add a new document if none of the documents match the name of the new user.

There are two ways to do that:

  1. Use a boolean variable to check if you're found a matching name, setting it to true in the loop if you find a match. Then after the loop, only add the new document if the variable is still false.

  2. Use a query to only load documents with the username that the new user entered.

While #1 is closest to your existing code, it requires that you load all user documents. That would get slower and slower as your app gets more users, so is not recommending. I'd instead go with approach #2 and use a query.

That'd look something like this:

db.collection("Users")
  .whereField("username", isEqualTo: username)
  .getDocuments { (querySnapshot, error) in
    if let error = error {
        print("Error connecting to database")
    }
    else {
        if querySnapshot.isEmpty {

            let userID = Auth.auth().currentUser!.uid

            if let name = self.nameField.text, let email = self.emailTextField.text, let username = self.usernameTextField.text {
                self.db.collection("Users").document("\(userID)").setData(["name":name,"email":email, "username":username, "accountBalance": 0]) { (error) in

                    if error != nil {
                        print("Error saving data")
                    }
                    else {
                        self.performSegue(withIdentifier: "signedUp", sender: self)
                    }
                }
            }
        }
    }
}

Also see: