简体   繁体   中英

How do I get Firebase to add new users and not overwrite current users (iOS, Xcode 8)?

This code keeps overwriting the database after a new user is created. This is the code that I have put in:

func handleRegister() {
    guard let email = emailTextField.text, let password = passwordTextField.text, let name = nameTextField.text
        else {
            print("Form is not Valid")
            return
        }

    Auth.auth().createUser(withEmail: email, password: password, completion: {(user: User?, error) in
        if error != nil {
            print(Error.self)
            return
        }

        guard (user?.uid) != nil else { return }
    })

    let ref = Database.database().reference(fromURL: "//Firebase link")
    let usersReference = ref.child("Users").child("uid")
    let values = ["name": name, "email": email]

    usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
        if err != nil {
            print(err.self)
            return
        }
        print("Successfully saved user in Firebase DB")
    })
}

I feel like I'm missing something really simple. Any help would be appreciated.

EDIT: after your

guard (user?.uid) != nil else {
  return
}

put your remaining code below it:

let ref = Database.database()... //your code
//put inside the completion block of create user
//the rest of your code up to the updateChildValues

and use this uid as the parameter for your child in users

so it would become:

let usersReference = ref.child("Users").child(uid)

note that the uid is not enclosed with double quotes

you have to put it inside the createUser completion block because the scope of your user?.uid is only up to that block.

use below code as in your code everytime you run handler data is replaced as you are providing static "uid" use below code to add a node with current user uid which is assigned to user at time of account creation in firebase DB

//before viewDidLoad declare a global databaseRef as

let  databaseRef = Database.Database().reference //this will be used as base reference In all handlers 
var name : String = ""
var Uid : String = ""
var email : String = ""
var nameString : String = ""

func createUser(){
    Auth.auth().createUser(withEmail: self.EmailTextField.text!, password: self.PasswordTextField.text!) { (user, error) in

        if error == nil {
            print("You have successfully signed up")
            //Goes to the Setup page which lets the user take a photo for their profile picture and also chose a username

            self.nameString = self.nameTextField.text!

            self.AddUserDetails()

            DispatchQueue.main.async(execute: {
                let vc = self.storyboard?.instantiateViewController(withIdentifier: "Main")
                self.present(vc!, animated: true, completion: nil)
            })

        } else {
                 //this block shows error if exist
                 let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)

            let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
            alertController.addAction(defaultAction)

            self.present(alertController, animated: true, completion: nil)
            //this is my activity indicator
            self.spinnerView.isHidden = true
            self.spinner.isHidden = true
            self.spinner.stopAnimating()
        }
    }
}

func AddUserDetails(){
    //I make use of user nsobject class to get all details
    //you can also make use of some global strings
    self.name = self.nameString //name string store current display name
    //name string contains name which I am taking as input when a user want to sign up as a textField text
    self.email = (Auth.auth().currentUser?.email)! //current email
    self.Uid = (Auth.auth().currentUser?.uid)! //current uid


    let user:[String : AnyObject] = ["email": self.email as AnyObject,"name":self.name as AnyObject,"uID":self.Uid as AnyObject]

    databaseRef.child("users").child(self.Uid).setValue(user)

}

you are not calling your code to write in database inside the callback of user creation. So its creating user reference with old uid and hence overwrite the values.

 Auth.auth().createUser(withEmail: email, password: password, completion: {(user: User?, error) in

        if error != nil {
        print(Error.self)

        return
    }
// after this you are sure user created and now move your calls here 
//to write in firebase database.
    guard (user?.uid) != nil else {
        return
    }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM