Select a user from Firestore - ios

I can not solve the problem: In Firestore there is a collection of user, in which there are several documents with fields (email: "String", name: "String", password: "String"). In the textField, the email and password are entered, it is necessary to write a function that selects a specific user from Firestore from the entered data. The function entranceLogin ():
func entranceLogin() {
guard let email = emailTextField.text, let password = passwordTextField.text else{
print("Form is not valid")
return
}
let values1 = [email]
let values2 = [password]
var db = Firestore.firestore()
db.collection("users").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
db = document.value(forKey: "email = '\(values1)' && password = '\(values2)'") as! Firestore
print("\(db) => \(document.data())")
}
// self.dismiss(animated: true, completion: nil)
}
}
}

It is very unsafe to store a password in the database the way you are doing it. Firebase already provides you with a login function
Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
//.....
}
Then in your database instead of saving the password, just save the User UID for each of the users. Then you can fetch the user by using:
guard let uid = Auth.auth().currentUser.uid else { return }
Firestore.firestore().collection("users").whereField("userID", isEqualTo: uid).getDocuments() { snapshot, error in
// Do user fetching here
}

Related

Trying To createUser with Firebase and when i am using Auth.auth().createUser(withEmail: email, password: password) give me an error

enter image description here
#error >> Type of expression is ambiguous without more context.
Auth.auth().createUser(withEmail: email, password: password) { AuthDataResult, error in
// handle error
if let error = error {
print("Failed to create a user with error", error.localizedDescription)
return
}
// set profile image
guard let profileImage = self.plusPhotoButton.imageView?.image else { return }
//upload data
guard let uploadData = profileImage.jpegData(compressionQuality: 0.3) else { return }
// place image in database
let filename = NSUUID().uuidString
let storageRef = Storage.storage().reference().child("profile_image").child(filename)
storageRef.putData(uploadData, metadata: nil, completion: {(metadata, error) in
// handle error
if let error = error {
print("Faild to upload image to firebase storage with error", error.localizedDescription)
}
// profile image URL
guard let profileImageURL = metadata?.downloadURL()?.absoluteString else { return }
//user Id
guard let uid = AuthDataResult?.user.uid else { return }
//guard let fcmToken = messaging.messagin().fcmToken else { return }
let dictionaryValues = ["name": fullName,
"username": username,
"profileImageURL": profileImageURL]
let values = [uid: dictionaryValues]
//save data info to database
Database.database().reference().child("users").updateChildValues(values, withCompletionBlock: { (error, ref) in
print("Successfully created user and saved indformation to database")
})
})
}
i import Firebase but still not working.

CreateNewUser() firebase method is returning nil in the closure for user uid

I am trying to authenticate users. But the createNewUser() firebase method is returning nil in the closure for user?.user.uid and thus I cannot add the data under the correct node.
Bellow is my user creation method:
func createNewUser(email: String, password: String) {
Auth.auth().createUser(withEmail: email, password: password) { user, error in
if error == nil && user != nil { //user create works
print(user, "<-- User Created (user)")
} else { //user not create
print("Error creating user: \(error!.localizedDescription)")
}
//database integration
let ref = Database.database().reference()
let usersRef = ref.child("users2")
let uid = user?.user.uid
print(email, "<-- email")
print(uid, "<-- this is uid")
let newUserRef = usersRef.child(uid!)//This fails because UID is nil
newUserRef.setValue(["email": self.emailTextField.text!, "password": self.passwordTextField.text!, "fullName": self.fullNameTextField.text!, "username": self.usernameTextField.text!])
print(email, "<--- this is emaiL??")
} //end of create user
}
How do I fix this?
When I look at the docs for Firebase's "createUserWithEmail:password:completion:" method, it looks like you get an authResult, error back from Auth.auth().createUser(withEmail:....
And from that, to get the user, you'd do:
func createNewUser(email: String, password: String) {
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
guard let authResult = authResult, error == nil else {
print("Error creating user: \(error!.localizedDescription)")
return // an error!
}
if let user = authResult.user {
if let uid = user.uid {
print("uid is \(uid)")
}
if let email = user.email {
print("email is \(email)")
}
}
...
...
...

Authenticated User entry are not saved in Database

#objc func registerButtonClicked()
{
//After Firebase is configured this is called
guard let email = emailTextField.text else {
alertBox(title: "Error", message: "All fields are mandatory")
return }
guard let password = passwordTextField.text else { return }
guard let name = nameTextField.text else { return }
Auth.auth().createUser(withEmail: email, password: password) { (data, error) in
if error != nil{
print(error.debugDescription)
print("Error occurred")
} else
{
print("Data -- >\(String(describing: data))")
self.saveDataInFirebase(name: name, password: password, email: email)
//here the data is saved in authentication table in firebase so next step //was to save its detail in db in json
}
}
}
func saveDataInFirebase(name: String, password: String, email: String)
{
let userData = ["name" : name, "email" : email]
print("name \(name) --- Email \(email)")
// printing the details to be saved in DB
let firebaseRef = Database.database().reference(fromURL: "https://chatdemo1-d3423.firebaseio.com/")
firebaseRef.updateChildValues(userData) { (error, dbRef) in
if error != nil{
print("------------------")
print(error.debugDescription)
print("----------------------")
}
else
{
print("Data Saved Successfully")
}
}
}
The code in the question is probably not what you want to use as it will overwrite your entire Firebase each time it's run.
The reason for that is you're not writing data to a child node of your Firbase, you are writing it to the main node. This is what's being written:
your_firebase //<- this is where you're writing too each time
email: "some email"
name: "some name"
my guess is you want to stucture it like this
your_firebase
user_id
email: "some email"
name: "some name"
and the code to do that would be
var ref: DatabaseReference!
func viewDidLoad() {
self.ref = Database.database().reference()
.
.
.
}
func createUser() {
let email = "some email"
let password = "some password"
let name = "some name"
Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
if let x = error { //some fancy error checking
let err = x as NSError
switch err.code {
case AuthErrorCode.emailAlreadyInUse.rawValue:
print("email in use!")
default:
print("unknown error")
}
} else {
guard let user = authResult?.user else { return }
let uid = user.uid
let usersRef = self.ref.child("users")
let thisUserRef = usersRef.child(uid)
thisUserRef.child("email").setValue(email)
thisUserRef.child("name").setValue(name)
}
}
}
This code assumes the Firebase Rules allows the user permission to write the the users node

How to write registered user into database in Swift?

When i select register.. the data is sent to Firebase authentication but does not store in the database? Can anyone tell me where im going wrong?
func handleRegister(){
// Validation
guard let email = emailTextField.text, let password = PassTextField.text, let name = nameTextField.text
else{
print("Please provide an Email and Password")
return
}
FIRAuth.auth()?.createUser(withEmail: email, password: password, completion: { (user: FIRUser?, error) in
if error != nil {
print(error!)
return
}
// Successfully authenticated user
// Saving Data to the Database
let ref = FIRDatabase.database().reference(fromURL: "https://chat-47e5b.firebaseio.com/")
let values = ["name": name, "email": email]
ref.updateChildValues(values, withCompletionBlock: { (err,ref)
in
if err != nil {
print(err!)
return
}
print("Saved user successfully into Firebase")
})
})
}
You are not doing it right, you should first get a reference to the db:
self.ref = FIRDatabase.database().reference()
Then:
let values = ["name": name, "email": email]
self.ref.child("users").child(user.uid).setValue(values)
As a side note, convert this:
if error != nil {
print(error!)
return
}
To this:
guard let error = error else {
print(error)
return
}

Firebase iOS: createUserWithEmail isn't generating userId (uid)

I am new to firebase and I'm trying to learn how to create users. My problem is that when i use the createUserWithEmail completion block via a button, for some reason the unique identifier, the uid, is not generated. This prevents me from storing the associated username and password under the uid in the JSON tree. My code is as follows (I have defined databaseRef in a separate swift file as a global constant using "let databaseRef = FIRDatabase.database().reference()")
#IBAction func createAccount(sender: AnyObject) {
var username = usernameField.text
var email = emailField.text
var password = passwordField.text
if username != "" && email != "" && password != "" {
FIRAuth.auth()?.createUserWithEmail(email!, password: password!, completion: { (user, error) in
databaseRef.child("users/(user.uid)/username").setValue(username)
databaseRef.child("users/(user.uid)/password").setValue(password)
databaseRef.child("users/(user.uid)/uid").setValue(user?.uid)
})
} else {
print("please complete all fields")
}
}
I know the uid is not generated for two reasons. Firstly, when i run the above code and enter in values for each of my texts fields, the app crashes. Secondly, if i delete the code that deals with setting the values and replace it with print(user.uid), a value of nil is returned. What am i missing? I can understand that the uid is a very important part of creating a user.
***Here is the solution I came up with
#IBAction func createAccount(sender: AnyObject) {
var username = usernameField.text
var email = emailField.text
var password = passwordField.text
if username != "" && email != "" && password != "" {
FIRAuth.auth()?.createUserWithEmail(email!, password: password!, completion: { (user, error) in
if let user = FIRAuth.auth()?.currentUser {
databaseRef.child("users/\(user.uid)/username").setValue(username)
databaseRef.child("users/\(user.uid)/password").setValue(password)
databaseRef.child("users/\(user.uid)/email").setValue(email)
print(user.uid)
} else {
print("no user")
}
})
} else {
print("please complete all fields")
}
Swift 4, 2018 solution for anyone who's interested:
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
// guard against errors and optionals
guard error == nil else { return }
guard let user = user else { return }
let userObject = [
"uid": user.uid,
"username": username,
"password": password, // I don't recommend storing passwords like this by the way
"email": email
] as [String:Any]
databaseRef.child("users").child(user.uid).setValue(userObject)
}
Swift 5.1, 2022 solution for anyone who's interested:
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
// guard against errors and optionals
guard error == nil else { return }
guard let user = user else { return }
let userObj = ["uid": user.user.uid, "username": username, "email": email] as [String:Any]
databaseRef.child("users/\(user.user.uid))".setValue(userObj)

Resources