Pretty new to Firestore. Is there a way to get ID or reference to a newly created document?
firestore.collection(myCollection).document().setData(["myData": data]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
Any kind of help is highly appreciated.
You can get it before the document is created, because it's generated on the client when you create the DocumentReference.
let ref = firestore.collection(myCollection).document()
// ref is a DocumentReference
let id = ref.documentID
// id contains the random ID
ref.setData(...)
Related
I am struggling to understand why my event listener that I initialize on a document is not being triggered whenever I update the document within the app in a different UIViewController. If I update it manually in Google firebase console, the listener event gets triggered successfully. I am 100% updating the correct document too because I see it get updated when I update it in the app. What I am trying to accomplish is have a running listener on the current user that is logged in and all of their fields so i can just use 1 global singleton variable throughout my app and it will always be up to date with their most current fields (name, last name, profile pic, bio, etc.). One thing I noticed is when i use setData instead of updateData, the listener event gets triggered. For some reason it doesn't with updateData. But i don't want to use setData because it will wipe all the other fields as if it is a new doc. Is there something else I should be doing?
Below is the code that initializes the Listener at the very beginning of the app after the user logs in.
static func InitalizeWhistleListener() {
let currentUser = Auth.auth().currentUser?.uid
let userDocRef = Firestore.firestore().collection("users").document(currentUser!)
WhistleListener.shared.listener = userDocRef.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else {
print("Error fetching document: \(error!)")
return
}
guard let data = document.data() else {
print("Document data was empty.")
return
}
print("INSIDE LISTENER")
}
}
Below is the code that update's this same document in a different view controller whenever the user updates their profile pic
func uploadProfilePicture(_ image: UIImage) {
guard let uid = currentUser!.UID else { return }
let filePath = "user/\(uid).jpg"
let storageRef = Storage.storage().reference().child(filePath)
guard let imageData = image.jpegData(compressionQuality: 0.75) else { return }
storageRef.putData(imageData) { metadata, error in
if error == nil && metadata != nil {
self.userProfileDoc!.updateData([
"profilePicURL": filePath
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("Document successfully updated")
}
}
}
}
}
You can use set data with merge true it doesn't wipe any other property only merge to specific one that you declared as like I am only update the name of the user without wiping the age or address
db.collection("User")
.document(id)
.setData(["name":"Zeeshan"],merge: true)
The answer is pretty obvious (and sad at the same time). I was constantly updating the filepath to be the user's UID therefore, it would always be the same and the snapshot wouldn't recognize a difference in the update. It had been some time since I had looked at this code so i forgot this is what it was doing. I was looking past this and simply thinking an update (no matter if it was different from the last or not) would trigger an event. That is not the case! So what I did was append an additional UUID to the user's UID so that it changed.
i want to get document's id's from firestore and store them in a variable to use in my next page.
how can i do this with swift? i tried this method but it generates a random id not the specific document id of the collection that i have
let docRef = Firestore.firestore().collection("Shops").document()
let docId = docRef.documentID
attached are the document id's i need to retrieve in my variable.
You can use getDocuments() to fetch all documents in one collection or use .addSnapshotListener() to automatically fetch new documents.
Firestore.firestore().collection("Shops").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID)") // Get documentID
print("\(document.data)") // Get all data
print("\(document.data()["name"] as! String)") // Get specific data & type cast it.
}
}
}
I'm trying to run through a loop to batch delete all of a particular event's eventPosts (pictures) however I'm running into the following error:
Cannot convert value of type 'QueryDocumentSnapshot' to expected argument type 'DocumentReference'
I know I'm missing something just not sure what it is, here's the loop:
db.collection("posts").whereField("eventId", isEqualTo: eventId).getDocuments() { (snapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
}
else {
for document in snapshot!.documents {
batch.deleteDocument(document)
}
// Commit the batch
batch.commit() { err in
if let err = err {
print("Error writing batch \(err)")
} else {
print("Batch write succeeded.")
}
}
}
Replace
batch.deleteDocument(document)
with
batch.deleteDocument(document.ref)
As you can see in the official documentation the deleteDocument() method should receive the ref to a document as a parameter.
Using Swift 4, Firebase Auth, Firebase Cloud Firestore.
I have a chat DB and a user DB. I am using phone authentication with Firebase and am saving the UID to store for each user in the user DB. For each chat DB, I am storing the current user's UID to allow a lookup to happen. It's here where I am stuck. Is there anyway I can get all chats from a specific user if the sender ID is a attribute to each document in the chat DB?
I actually figured it out
func getChatsFromUser() {
let db = Firestore.firestore()
db.collection("chats").whereField("senderID", isEqualTo: String(describing: Auth.auth().currentUser!.uid))
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
}
Loading data from firestore while offline works as expected but a call to save never returns and there seems to be no timeout either.
This is a example save that works online but not offline:
func save() {
guard let uid = user?.uid else {
return
}
let db = Firestore.firestore()
var ref: DocumentReference? = nil
ref = db.collection("users").document(uid).collection("properties").addDocument(data: ["name": "test"]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
}
Is there any known workaround?
UPDATE: Firebase support have confirmed it's a bug and that it "is now being worked on by our engineers". They are unable to give a timescale for when it will be fixed.
This is the expected behaviour - you should assume that the write will happen when the device comes back online. In my use cases, I've just continued with the normal flow and used my local data as my source of truth.
It's mentioned here: https://youtu.be/XrltP8bOHT0?t=680