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:
- Login to user's account
- 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
- 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
How to Compare Two Strings to Check If They Have Same Characters Swift 4
How to Get All Text from a PDF in Swift
Swift: Implementing Protocol Initializer in a Class
Simple Swift Class Does Not Compile
Passing Unknown Number of Arguments in a Function
Randomize Two Arrays the Same Way Swift
Tests for Custom Uitableviewcell, Cellforrowatindexpath Crashes with Nil Outlets
Equivalent of Skaction Scaletox for a Given Duration in Unity
Why Do We Need to Specify Init Method
Swift Switch Char{ Case "\U{E2}:
How to Run the Simulator the Operation Couldn't Be Completed. (Launchserviceserror Error 0.)
Swift Check If Value Is of Type Array (Of Any Type)
Auth.Auth().Currentuser.Reload() Doesn't Refresh Currentuser.Isemailverified
Swift Issue in Passing Variable Number of Parameters
Ios8: Auto-Layout and Gradient
Accessing Struct from One Class to Another
Loading Uiviewcontroller from Instantiateviewcontrollerwithidentifier - Nil Outlets