Add subcollection in cloud firestore using swift - swift

I have a simple problem. I have an existing document in cloud firestore and I simply want to add a subcollection to this document and add a document to this subcollection.
The following is my code for what I believe should do the job, but unfortunately doesn't. Also I dont get any errors.
var ref: DocumentReference? = nil
ref = db.collection("users").document("John").collection("newSubcollection").addDocument(data: [
"age": 25
]) { error in
if let err = err {
print("Error adding subcollection: \(err)")
} else {
print("subcollection added with ID: \(ref!.documentID)")
self.dismiss(animated: true, completion: nil)
}
}
The message I get is that it succesfully created the subcollection, but I dont see it. What is going wrong?

Related

firebase users collection has document of users with strange ID

I;m new to firebase, I've users collection with documents, but the ID's are not know for me, I don't know how to access them, I tried with uid but those ID's doesn't look like uids therefore It didn't work
as you can see in the screenshot above, documents ids are different from users uids my target is to access user, after that document and add a new collection ( of course not in all users, the registered one.
any ideas how to access them?
// create user
Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
// check for errors
if let err = err {
// error occuried
showError("error while creating user")
}else {
// user was created succesfully,store name and vaccine
let db = Firestore.firestore()
db.collection("users").addDocument(data: ["username":self.usernameLabelRegister.text ,"vaccine":self.chosenVaccine,"nationality":self.chosenLocation, "uid":result!.user.uid,"profileImageUrl":RegisterViewController.staticProfileImageUrlString]) { error in
if error != nil {
// show error
showError("user data blablabla")
}
}
You are indeed adding a document with random ID (which is not same as user's UID). Instead use setData where you can specify the ID:
// Pass user ID from result of createUser
db.collection("users").document(result.user.uid).setData(data: ["username":self.usernameLabelRegister.text ,"vaccine":self.chosenVaccine,"nationality":self.chosenLocation, "uid":result!.user.uid,"profileImageUrl":RegisterViewController.staticProfileImageUrlString]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}

Retrieving Manually Inputted Data Firestore

Would it be possible to create documents in Firestore and then later reference it within swift/xcode/app? I want to manually add restaurant data into Firestore and then reference the data (city,type, phone number, etc.) within an app.
What do you recommend I do to be able to retrieve the manually typed out document entries?
Yes this is possible and not that hard to figure out when you look at the offical docs.
SDK IOS SETUP
https://firebase.google.com/docs/ios/setup
Getting started with firestorehttps://firebase.google.com/docs/firestore/quickstart#ios
Creating a new document in the collection "USERS"
// Add a new document with a generated ID
var ref: DocumentReference? = nil
ref = db.collection("users").addDocument(data: [
"first": "Ada",
"last": "Lovelace",
"born": 1815
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
Reading that data
db.collection("users").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
For referencing documents made by users you could safe the UserID to the firestore document and filter the documents in the app by Current user ID.
This is mostly used in apps.
I would also suggest to watch some videos from:
https://peterfriese.dev/
This will give you a clear understanding on what to do with the data you get back.

How to make app automatically recognise current user Firestore document ID when signed in?

When a user is signed up through my form, a document gets created associated with that user. My main goal is to create a global function that can recognize the user that is signed in and get their document ID. I have a function setup for adding documents to a subcollection of the user document which is perfectly setup, the only downfall is that when I'm testing with multiple accounts, I have to manually switch the collection path. Here is what I mean.
#IBAction public func createEventButton(_ sender: UIButton) {
let error = validateFields()
if error != nil {
showError(error!)
} else {
db.collection("school_users/\(stThomas)/events").addDocument(data: ["event_name": nameTextField.text, "event_date": dateTextField.text, "event_cost": costTextField.text, "for_grades": gradesTextField.text]) { (error) in
if error != nil {
self.showError("There was an error trying to add user data to the system.")
} else {
self.dismiss(animated: true, completion: nil)
}
}
}
So as you can see here, I am using string interpolation with the "stThomas" constant I used to store a document ID. I basically want to create a function that will recognize the document ID of the user signed in so I can use my Constants instead of string interpolation and having to manually switch the user collection path each time, which would be eventually impossible during production.
Not to mention, I do have a function to grab the document ID, say for instance an event is clicked, but as a beginner in Swift, I can't seem to connect the dots. I will also show this function for clarification.
func getDocID() {
db.collection("school_users/\(notreDame)/events").getDocuments() { (querySnapshot, error) in
if let error = error {
print("There was an error getting the documents: \(error)")
} else {
self.documentsID = querySnapshot!.documents.map { document in
return DocID(docID: (document.documentID))
}
self.tableView.reloadData()
}
}
}
And in this function you can see my other constant "notreDame" with another stored document ID. If anybody knows a simple way to do this that would be great. And yes, I checked the Firebase documents, thank you for asking.
I've did some extra research and realized that I can use User IDs in collection paths. My problem is now solved. Many more problems to come though.

How can I add a new document with fields to a firebase collection with the autoid in swift ui

I would like to add a document to my database collection using autoid with fields that I assign the name to in swift ui .
Get a reference of the database:
var db: Firestore!
then you can reference it with:
db.collection()
For example, if I wanted to add a person's name under a unique id:
db.collection("users").addDocument(data: [
"name": nameTextField.text // Change this to the variable you want to save
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
If you create the document without an explicit Id, our SDK will auto-generate a random one for you.
The docs are a good source of information too.

Firestore how to store reference to document / how to retrieve it?

I am new to Firestore/Firebase and I am trying to create a new document with one of the fields being a document reference to an other document. I have read all the guides and examples from Firebase and did not find anything...
Also, when I retrieve this document I created, I would be able to access what is inside the reference I added inside. I have no idea how to do that.
Here is some code I tried for the creating part
let db = Firestore.firestore()
// Is this how you create a reference ??
let userRef = db.collection("users").document(documentId)
db.collection("publications").document().setData([
"author": userRef,
"content": self.uploadedImagesURLs
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
You're just missing one step. This took me a while to figure out as well.
First, store a variable DocumentReference!
var userRef: DocumentReference!
Then, you want to create a pointer to the document ID — create a DocumentReference from that <- this part you are missing
if let documentRefString = db.collection("users").document(documentId) {
self.userRef = db.document("users/\(documentRefString)")
}
Finally, resume saving your data to the database
db.collection("publications").document().setData([
"author": userRef,
"content": self.uploadedImagesURLs
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
Hope that helps!
This way works perfectly for me:
let db = Firestore.firestore()
let documentRefString = db.collection("users").document(documentID)
let userRef = db.document(documentRefString.path)
Then, when you will set the data:
db.collection("publications").document().setData([
"author": userRef,
"content": self.uploadedImagesURLs
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}