J.G. Homework
J.G. Homework

Reputation: 53

How do I validate if a username exists before sign up in Firebase and Swift 3?

I've incorporated a sign-up flow of five view controllers as opposed to one central VC for Firebase sign up.

Normally there would be the problem of data being lost before sign up, but I'm pushing all the entered values via segue programmatically to the final confirmation page and sending the data to Firebase for auth eventually.

My problem lies therein - I want to check if the username exists before signing up. This is imperative for the UX of my app and I can't just do this all one VC.

Here's the code I have for the UsernameViewController:

   let rootRef = FIRDatabase.database().reference()

   rootRef.queryOrdered(byChild: "users").queryEqual(toValue: self.chooseUsernameTextField.text!)
    .observe(FIRDataEventType.value, with: { (snapshot: FIRDataSnapshot!)  in

            if snapshot.hasChildren() == false {
                print("not found")

            } else {
                print("usr found")
            }
        });

Here's the code I have for the Firebase Database Security Rules

   {
     "rules": {
        ".read": false,
        ".write": false,
      "users": {
        ".validate": "data.child('username').val() === true",
      ".read": true
      }
     }
    }

and finally, a screenshot of my Data tree (My Data tree won't let me nest any new users or create a user node without a value for some reason):

Picture of Firebase Data Tree: App Name/Users

I have a nagging suspicion that my data rules and tree are configured properly to match the code, but I'm stuck in a XY problem of not knowing what to do for Firebase security to get my code of username checking complete.

Please help me! :(

Upvotes: 2

Views: 1417

Answers (3)

Badr Bujbara
Badr Bujbara

Reputation: 8671

When using Firestore to save users, I did this

 Auth.auth().addStateDidChangeListener({ (auth, user) in 
     if let id = user?.uid{ 
        let userDoc =  db.collection("users").document(id)
        userDoc.getDocument { (document, error) in
            if document == nil{// if user doesn't exist, create one
                self.db.collection("users").document(id).setData(userProfile.toDictionary()){ error in

                }
            }
        }
    }
    })

Upvotes: 0

Abishek Gokal
Abishek Gokal

Reputation: 186

I have not tested the code but the theory would be to order by username that equals to the username you are looking for. If this snapshot exists you already have a user in the database with that name if it doesn't you do not.

Will run and test code when i have a chance to and update my post.

 let rootRef = FIRDatabase.database().reference()

      rootRef.child("users").queryOrdered(byChild:"username").queryEqual(toValue:   self.chooseUsernameTextField.text!)
    .observe(.value, with: { (snapshot)  in

            if snapshot.exists() == false {
                print("not found")

            } else {
                print("usr found")
            }
        });

Upvotes: 2

MQLN
MQLN

Reputation: 2328

If there's a user created within the Auth section of Firebase as well, then you can actually use the fetchProviders method, and if no providers are returned, you have no user in you Auth section.

FIRAuth.auth()?.fetchProviders(forEmail: email, completion: { (providers, error) in
            if providers == nil {
                   // user doesn't exist
              } else {
                   // user does exist
              }
        })

Upvotes: 3

Related Questions