I'm trying to create a simple user database on Firebase for iOS. I have two textfields, one that takes the user's email address, and the other that takes the user's password. I want the email to be the user's uid. I try to accomplish this by creating a variable called "email" which I set equal to emailTextField.text! Then I implement the code that generates child(s) in Firebase, like so:
ref = Database.database().reference()
ref.child("users").child(email).setValue(true)
Here's my problem: creating a child and naming it using a variable, doesn't work. I can do the following just fine:
ref.child("users").child("email")
but once I take away the quotation marks around "email" so that it becomes the variable, the program crashes.
How can I use user input to name a child in Firebase?
Firebase node / document names do not support the same character set which email addresses support, for example, the . symbol in an email address would make the child name invalid.
If you tried setting a child as
ref.child("users").child("xyz#xyz.xyz")
you should see the same error.
If you absolutely need to use the email address as the node name, I recommend encoding the email in a way which is compatible with the firebase node name rules.
Link to the rules
Edit: If you are using firebase auth, the normal pattern is too use the UID returned by the authenticated user object as the node name, not the email address entered from the textfield.
A quick example:
Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
if let user = user {
ref.child("users").child(user.uid).setValue(true)
}
}
Related
When registering a new user, and when I look in the Firebase user database, if the user exists he does not create the accunt, otherwise the registration is completed. But if there is a user named "Tony" in the database and I try to register with the username "tony", Firebase don't understand that "Tony" and "tony" are the same username. I want to solve this.
I state that I wrote the code in swift.
I think the fastest way with querying is to do this:
Duplicate your username list in a new list where all your usernames are lowercased
Lowercase the new username
Check if that username exist in your duplicated list (where all usernames are lowercased)
When it does not exists, append the real username without lowercase to the list with the usernames where they are case-sensitive and to the lowercased username list.
This duplicates data, but it is not that bad since it are only usernames.
This question already has answers here:
How do I return a list of users if I use the Firebase simple username & password authentication
(7 answers)
Closed 6 years ago.
I want to show list of users in my app. I use default Auth system from firebase. But response always empty.
FIRDatabase.database().reference().child("users").queryOrdered(byChild: "email").observe(.value, with: { snapshot in
print(snapshot)
})
But snapshot is always Snap (users) <null>
The Firebase Authentication system does not automatically insert anything into the Firebase Database. I guess your database is empty, which is the reason for snapshot being null.
Your code looks correct, but as I said there might not be any data in your database to receive.
Depending on what exactly you want to achieve you should consider storing user meta data in you database. A good point to do so would be directly after the user creation.
Registering a user with Firebase Authentication, by default, does nothing to modify your Firebase Database. Authentication and Database are two pretty much unrelated services. It's a common practice, once you register a user, to save an entry in your Database with their uid, so you can relate the two services:
let auth: FIRAuth? = FIRAuth.auth() // The authentication object
auth?.createUser(withEmail: email, password: password) { (user, error) in
// If registration was successful, `user` is a FIRUser with a uid
if let userId = user?.uid {
let exampleDBPath = FIRDatabase.database().child("users").child(userId)
// Write the user object, for instance a user name or other data, to this path
exampleDBPath.setValue(someJSONAboutTheUser) { (error, result) in
// Now you have a spot to modify your user in the database
}
}
}
This FIRUser created from registration is the same type of object you'll get when a user tries to sign in, so you can find the correct user in the database via the same uid.
I am using Parse in my Xcode application and when I try to login with:
username: Admin
password: test
it works. But when I enter
username: admin
password: test
the login parameters are invalid. Is there a way to make Parse not case sensitive?
Basically what the link in the comment says is that when you create a new user object or before you let a user login call:
let username = usernameLabel.text
..........................
username = username.lowercaseString
..........................
//Then save the object
So it's not a way to make Parse case-insensitive but it eliminates the need to make it case-insensitive since everything is lowercased.
Some parameters Parse uses are case sensitive so it's up to you to implement the proper methods to rectify this before a user saves any User column properties. After the fact will be too late. So in short, let the user type whatever username they want and save it to the backend as a lowercase string. Then when they re-enter it, translate the user input string into another lowercase string and validate it against the backend (which is now a lower case representation)
I see that objectId of users generated locally and users created after anonymous login are not the same.
For example
PFUser.enableAutomaticUser()
let localUser = PFUser.currentUser()!.objectId!
print(localUserId) // "obj1"
PFAnonymousUtils.logInWithBlock {
(user: PFUser?, error: NSError?) -> Void in
let annonUserId: String = PFUser.currentUser()!.objectId!
print(annonUserId) // obj2
}
I want that obj1 to persist throughout the anonymous login phase.
Can I somehow "attach" the locally created user and login him anonymously? or is auto generated users are only useful for when you later upgrade him to a user&pass / social based logins ?
PFAnonymousUtils.logInWithBlock is defined to destroy existing anonymous user data and create a new clean anonymous user. You should only do that when the user is logged out.
If you enable anonymous users then one will be created initially and you can add whatever details you want to that. Then, later, when the user wants a real account use signUp: on the PFUser to convert it.
Note that anonymous users aren't real, you can't use them for everything. So, you may have some issues with them actually participating with other users. If this is the case then you may need to create real placeholder users with auto-generated login details and convert that at a later date by updating the username and sending a forgotten password e-mail (or similar).
I'm building an app where emails are supposed to be the main identifiers. I don't want my users to have a username at all. I'm using Parse for backend and want to use the PFUser class for user signups etc. It seems like PFUser requires a username. Is there anyway to use PFUser without using username?
You can set emailAsUsername to true in signUpView as following:
signUpViewController.signUpView.emailAsUsername = true
I am in the same situation as you, but what I do is just set the email address my user enters for the username field. Now they can just login with their email address :)