Firebase Username Uniqueness in Swift

Firebase querying for unique Username swift

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

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")
}
}

Firebase username uniqueness in Swift

Your problem is in your security rules. You're doing a query before the user has been authenticated. This query will fail because your rules state that the user has to be authenticated in order to query the database (auth != null).

What you need to do is create another child called "usernames". Make this readable by anyone without authentication. Check if the username is taken and if not, claim it for the new user. Then, do your auth call and create your user in the "users" child.

How to check unique username in Firebase Database (swift)

You still need to indicate what property you want to order/filter on with queryOrdered(byChild:):

if (usernameField.text?.isEmpty == false){
ref.child("users").queryOrdered(byChild:"username").queryEqual(toValue: username).observeSingleEvent(of: .value, with: { snapshot in

if snapshot.exists(){

Ensuring unique username on creating a new user in Firebase (Swift)

I'm currently investigating the same thing. My issue is that I also want persistence enabled, so I need to be aware of what can be accessed offline. If you're using persistence, I would also recommend disallowing particular operations such as checking username existence if your client is offline, which you can do by listening to ".info/connected" as further detailed here:

https://firebase.google.com/docs/database/ios/offline-capabilities#section-connection-state

My personal workflow for this is as follows:

  1. Login to user's account
  2. Check if the user already has a username

Check the firebase database to see if their user details includes a username:

DB/users/*userUID*/username != nil

  1. If they don't have a username, then prompt them to set a username.

When they set their username, check if the username exists in:

DB/usernames/*username*/ != nil

If it doesn't exist, then write the username and userId in the two database locations checked above.

eg.

user.uid = wewe32323

username = scuba_steve

DB/usernames/scuba_steve = wewe32323
DB/users/wewe32323/username = scuba_steve

So now you have the DB/usernames reference that you can check quickly to see if anyone has a username already, and you also have DB/users/ where you can quickly find a username for a given user.

I won't say this is fool-proof, as I still a few concerns around concurrent requests. My current issue I'm investigating is that lets say you delete the username association to a particular user, the user can depend on their local copy of the database to incorrectly assert that they are still assigned to that username.

You could look into the database write rules to disallow anyone to modify existing data (enforcing that you can only write to the DB/usernames directory if there is no existing data. This would prevent overriding of whoever sets the username first, which I think is an important step.

It may also be worth investigating Transactions:

https://firebase.google.com/docs/database/ios/save-data#save_data_as_transactions

But I believe correct write rules as mentioned in the paragraph above should allow dependable writing.

How to check the uniqueness of user-entered data in the Firebase database? swift

If each child of your users has an email property with the value you want to check, you can use a query to just retrieve the matching nodes.

Something like:

var query = ref.queryOrdered(byChild: "email").queryEqual(toValue: email.lowercased())

query.getData { error, snapshot in
...

Since all searches in Firebase are case-sensitive, this does require that your database contains all email addresses in lowercase already. If that's not the case, consider adding a property (say email_lowercase) with the lowercase value and using that in the query above.



Related Topics



Leave a reply



Submit