Home > front end >  Swift retrieve user info from firebase firebase firestore
Swift retrieve user info from firebase firebase firestore

Time:02-20

I want to retrieve the current logged in user Information (name and email) that was stored in the firestore in the registration function, the email and name should be displayed in textfield. i can retrieve the email successfully because I’m using the "Auth.auth().currentUser" and not interacting with the firesotre while the name is not working for me. what I’m suspecting is that the path I’m using for reaching the name field in firesotre is incorrect.

var id = ""
var email = ""

override func viewDidLoad() {
    super.viewDidLoad()
    userLoggedIn()
    
    self.txtEmail.text = email 
}
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)


 getName { (name) in
                if let name = name {
                    self.txtUserName.text = name
                    print("great success")
                }
            }
    
}

func getName(completion: @escaping (_ name: String?) -> Void) {
        guard let uid = Auth.auth().currentUser?.uid else { // safely unwrap the uid; avoid force unwrapping with !
            
            completion(nil) // user is not logged in; return nil
            return
        }
    print (uid)
    
        Firestore.firestore().collection("users").document(uid).getDocument { (docSnapshot, error) in
            if let doc = docSnapshot {
                if let name = doc.get("name") as? String {
                    completion(name) // success; return name
                } else {
                    print("error getting field")
                    completion(nil) // error getting field; return nil
                }
            } else {
                if let error = error {
                    print(error)
                }
                completion(nil) // error getting document; return nil
            }
        }
    }

func userLoggedIn() {
    if Auth.auth().currentUser != nil {
        id =  Auth.auth().currentUser!.uid
        //email = Auth.auth().currentUser!.email
    } else {
        print("user is not logged in")
        //User Not logged in
     }
    if Auth.auth().currentUser != nil {
        email = Auth.auth().currentUser!.email!
    } else {
        print("user is not logged in")
        //User Not logged in
     }
}

When I run this code the email is displayed and for the name "error getting field" gets printed so what I think is that the name of the document for user is not the same as the uid therefore the path I’m using is incorrect, the document name must be autogenerated. So is the solution for me to change the code of the registration function? can the user document be given a name (the userID) when I create the user document, instead of it being auto generarte it, if that’s even the case.

Here is the registration code for adding documents to firestore:

let database = Firestore.firestore()
    database.collection("users").addDocument(data: [ "name" :name, "email" : email ]) { (error) in
        if error != nil {
            //
        }

an here is a snapshot of my firestore users collection FireStore structure

CodePudding user response:

When creating a user;

Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
  // ...
}

At first you can only save email and password. (For now, that's how I know.) But after you create the user, you can update the user's name.

let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
changeRequest?.displayName = displayName
changeRequest?.commitChanges { error in
  // ...
}

Use userUID when saving user information in Firestore. If you drop the document into firebase, it will create it automatically. But if you save the user uid, it will be easy to access and edit.

func userSave() {
        let userUID = Auth.auth().currentUser?.uid
        
        let data = ["name": "ABCD", "email": "[email protected]"]
        Firestore.firestore().collection("users").document(userUID!).setData(data) { error in
            if error != nil {
                // ERROR
            }
            else {
                // SUCCESSFUL
            }
        }
    }

If you are saving user information in Firestore, you can retrieve information very easily.

func fetchUser() {
        let userUID = Auth.auth().currentUser?.uid
        
        Firestore.firestore().collection(“users).document(userUID!).getDocument { snapshot, error in
            if error != nil {
                // ERROR
            }
            else {
                let userName = snapshot?.get(“name")
            }
        }
    }

For more detailed and precise information: Cloud Firestore Documentation

If you see missing or incorrect information, please warn. I will fix it.

CodePudding user response:

There's a distinction between a Firebase User property displayName and then other data you're stored in the Firestore database.

I think from your question you're storing other user data (a name in this case) in the Firestore database. The problem is where you're storing it is not the same as where you're reading it from.

According to your code here's where it's stored

database.collection("users").addDocument(data: [ "name" :name, 

which looks like this

firestore
   users
      a 'randomly' generated documentID <- not the users uid
         name: ABCD
         email: [email protected]

and that's because addDocument creates a documentID for you

Where you're trying to read it from is the actual users UID, not the auto-created documentID from above

Firestore.firestore().collection("users").document(userUID!)

which looks like this

firestore
   users
      the_actual_users_uid  <- the users uid
         name: ABCD
         email: [email protected]

The fix it easy, store the data using the users uid to start with

database.collection("users").document(uid).setData(["name" :name, 
  • Related