1

I have a Firebase Auth that stores the users, but it also builds a collection of users in the Cloud Firestore database. I can grab the users first name, but the problem I have is that it is always the last user that was added.

here is my function in swift

func welcomeName() {

    let db = Firestore.firestore()
    if let userId = Auth.auth().currentUser?.uid {

    var userName = db.collection("users").getDocuments() { (snapshot, error) in
        if let error = error {
            print("Error getting documents: \(error)")
    } else {
        //do something
            for document in snapshot!.documents {
        var welcomeName = document["firstname"] as! String
        self.welcomeLabel.text = "Hey, \(welcomeName) welcome!"
                }
            }
        }
    }
}

in firebase cloud my users are stored as so

start collection is "users"

add document is the autoID

then collection is

firstname "Jane"

lastname "Doe"

uid "IKEPa1lt1JX8gXxGkP4FAulmmZC2"

any ideas?

Blue Moose
  • 125
  • 1
  • 15
  • Option1) Store your users data with the documentID being the users uid instead of autoID. Option 2) You could also perform a query for the specific users uid based on your current structure but queries are much 'heavier' than just directly reading a document so option 1 is the way to go. – Jay Oct 20 '19 at 14:51

2 Answers2

3

As you are looping through a list of all user documents so it will show last user's firstName on the label. You might want to show the first user as below,

if let firstUserDoc = snapshot?.documents.first {
   var welcomeName = firstUserDoc["firstname"] as! String
   self.welcomeLabel.text = "Hey, \(welcomeName) welcome!"
}

Or may be this for current user if uid in the list is same as userId,

if let currentUserDoc = snapshot?.documents.first(where: { ($0["uid"] as? String) == userId }) {
   var welcomeName = currentUserDoc["firstname"] as! String
   self.welcomeLabel.text = "Hey, \(welcomeName) welcome!"
}
Kamran
  • 14,987
  • 4
  • 33
  • 51
  • I figured that was what was happening. but what if the user is not first or last? how do I grab the user by who's logged in? – Blue Moose Oct 20 '19 at 05:03
  • @BlueMoose It is mentioned under **Or**. There must be some key to find which user a document belongs to. – Kamran Oct 20 '19 at 05:05
  • you were right. I think I deleted a bracket. now its working! thanks for the help! – Blue Moose Oct 20 '19 at 05:13
  • @BlueMoose Hold up here guys. While this is AN answer is not really going to be a good answer long term. As your app grows you could have thousands if not hundreds of thousand of users. With this solution, *every user in your entire database* has to be loaded along with *all of their user data* into the app, then iterate over those users until you find the right one. That could take very long time and could also overwhelm the device and crash. A better solution is to store users data in documents with their uid as the documentID and then you can directly read the users document you want. – Jay Oct 20 '19 at 14:50
  • @Jay I've never used `Firebase`. The answer is based on the information provided and your concern is completely valid. But `Firebase` already provide this query to fetch the list of documents for a particular `user`. – Kamran Oct 20 '19 at 16:34
  • 1
    Understood. However, what's in your answer is not what Firebase provides to query for a specific user. The answer iterates over every user that's already loaded looking for a specific one. Firebase has a discreet query that will return one and only one document, or user in this case, if the uid is known. To be clear, the answer is not wrong, but will not be a good solution as the app scales. – Jay Oct 20 '19 at 18:39
  • @Jay hmm that's interesting and makes sense! I added my signup page code that adds the new user. will this help me? In my cloud collection of users, I have first name last name and uid. but every time I try to use the documentation code that Firebase has it just shows last added. how can I fix this issue? – Blue Moose Oct 21 '19 at 02:19
1

You're users collection should look like this

users (collection)
   uid_0 (document that's the users uid)
      first_name: "William"
   uid_1
      first_name: "Henry"
   uid_2

Then, when the user authenticates, you will know their uid, so you can directly get the information from Firestore without a query.

func presentWelcomeMessage() {
    if let userId = Auth.auth().currentUser?.uid {
        let collectionRef = self.db.collection("users")
        let thisUserDoc = collectionRef.document(userId)
        thisUserDoc.getDocument(completion: { document, error in
            if let err = error {
                print(err.localizedDescription)
                return
            }
            if let doc = document {
                let welcomeName = doc.get("first_name") ?? "No Name"
                print("Hey, \(welcomeName) welcome!")
            }
        })
    }
}

If user William logs in, this will be printed to the console

Hey, William welcome!

Jay
  • 34,438
  • 18
  • 52
  • 81