How can I delete a Firestore field, using whereField? - ios

I'm trying to delete a field within a document, when the field "uid" matches the Current User's ID. I'm pretty stuck on this, and would appreciate any help. I detail, below, my code and how my database is set up.
#IBAction func deleteAccountButtonIsTapped(_ sender: Any) {
let db = Firestore.firestore()
let userID = Auth.auth().currentUser?.uid
let username = usernameTextField.placeholder
Auth.auth().currentUser?.delete(completion: { (error) in
if error != nil {
print("ERROR MAIN SETTINGS 136")
} else {
db.collection("FollowerList").whereField("uid", isEqualTo: userID!).getDocuments { (snapshot, error) in
for snapshot in snapshot?.documents {
}
}
}
}
)}
My Database has a collection "FollowerList", with documents named with the User's UID. Within these documents is a "uid" field, with the value of the User's UID.
Any help would be massively appreciated.

This should do the Job:
func deleteAccountButtonIsTapped(_ sender: Any) {
let db = Firestore.firestore()
let userID = Auth.auth().currentUser?.uid
let username = usernameTextField.placeholder
Auth.auth().currentUser?.delete(completion: { (error) in
if error != nil {
print("ERROR MAIN SETTINGS 136")
} else {
db.collection("FollowerList").whereField("uid", isEqualTo: userID!).getDocuments { (snapshot, error) in
if let snapshot = snapshot?.documents {
for doc in snapshot {
//Do delete
db.collection("FollowerList").document(doc.documentID).updateData([
"fieldToDelete": FieldValue.delete(),
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("Document successfully updated")
}
}
}
}
}
}
}
)}
One would think it could work like this:
But it doesn't as a value of type 'QueryDocumentSnapshot' has no member 'updateData'.
func deleteAccountButtonIsTapped(_ sender: Any) {
let db = Firestore.firestore()
let userID = Auth.auth().currentUser?.uid
let username = usernameTextField.placeholder
Auth.auth().currentUser?.delete(completion: { (error) in
if error != nil {
print("ERROR MAIN SETTINGS 136")
} else {
db.collection("FollowerList").whereField("uid", isEqualTo: userID!).getDocuments { (snapshot, error) in
if let snapshot = snapshot?.documents {
for doc in snapshot {
// How one would think it works but it doesnt
doc.updateData([
"capital": FieldValue.delete(),
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("Document successfully updated")
}
}
}
}
}
}
}
)}
See this page for further information:
https://firebase.google.com/docs/firestore/manage-data/delete-data#swift

Related

How to delete the Collections in firebase Cloud Firestore after n hours of its creation in Swift?

I am creating a database that can store people's data and I want to refresh the data in the "TimeSlot" path for every 24 hours. I need to delete the complete database once n hours are completed and start collecting a new set of data from the next day.
The link to the image is given Below.
This how my Database setup Looks like
// this is how I am creating the TimeSlot dataBase
#IBAction func bookASlot(_ sender: UIButton) {
let date = Date()
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateString = df.string(from: date)
let userMail = Auth.auth().currentUser?.email!
//search user table for entry that matches the current users email
db.collection("Users").whereField("email", isEqualTo: userMail as Any )
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
//if we are here there can be only ONE user with this email adress, since we are logged in
//so the array with our search results can contain only one entry
let document = querySnapshot?.documents[0]
let name = document?.documentID
let id = document?.get("uniqueId")
db.collection("TimeSlots")
.whereField("name", isEqualTo: name!)
.getDocuments { (querySnapshot, err) in
if let error = err {
print(error)
} else {
//there can, if any, only be one prior booking
if (querySnapshot?.count == 0) {
//None found -> book slot
db.collection("TimeSlots").document(name!).setData([
"name": name as Any,
"time": dateString,
"uniqueId": id!
]) { err in
if let err = err {
print("Could not book because of: \(err)")
} else {
print("Slot booked!")
}
}
} else {
print("already booked")
}
}
}
}
}
}
so once it is created then it should be stored for a certain number of hours and then the list should start a new after that period of time.
Sorry if I couldn't put my question Properly. Please and Thankyou
if you want delete all collenction path you need to do for loop all collection then call model and in the for loop you need to call again collection
let db = Firestore.firestore()
db.collection("Users").addSnapshotListener { querysnapshott, err in
if err != nil {
print(err?.localizedDescription ?? "error")
} else {
if querysnapshott?.isEmpty != true && querysnapshott != nil {
self.collectionmoldel.removeAll(keepingCapacity: false)
for document in querysnapshott!.documents {
let collection = collectionmodel(Name: document.get("name") as? String,
time: document.get("time") as? String,
documentID: document.documentID)
db.collection("Users").document(document.documentID).delete() { err in
if let err = err {
print(err.localizedDescription)
} else {
print("all path deleted")
}
}
}
}
self.tableview.reloadData()
}
}

Retrieve Firestore collection data - Error -Unexpectedly found nil while implicitly unwrapping an Optional value

I have been working on Firestore for retrieving data, when I tried to get data from collection->document id-> field. refer the below screen shot, I need to check companyCode matches with user entered companyCode.text
I tried with below code, need to check whether the user entered companyCodeLabel.text matches document "companyCode" and also get documentId. Can anyone suggest how to solve this?
guard let code = companyCodeLabel.text else { return }
let docRef = db.collection("Company").whereField("companyCode", isEqualTo: code).limit(to: 1)
docRef.getDocuments { (querysnapshot, error) in
if error != nil {
print("Document Error: ", error!)
} else {
if let doc = querysnapshot?.documents, !doc.isEmpty {
print("Document is present.")
}
}
}
Even tried to print the field value in collection but still have crash and same error nil
self.db.collection("Company").getDocuments { (snapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in snapshot!.documents {
let docId = document.documentID
let compCode = document.get("companyCode") as! String
let compName = document.get("companyName") as! String
print(docId, compCode, compName)
}
}
}
I tried to call in wrong db, I was trying var db = Firestore!,
The correct solutions is
Firestore.firestore().collection("Company").getDocuments { (snapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in snapshot!.documents {
let docId = document.documentID
let compCode = document.get("companyCode") as! String
let compName = document.get("companyName") as! String
print(docId, compCode, compName)
}
}

How to update user information in firebase?

i have this function to change user email. I'm able to change the email and i can see it in firebase console, but when i go return to my application to see user info, i see only the old email presented.
#IBAction func saveButton(_ sender: Any) {
let currentUser = Auth.auth().currentUser
currentUser?.updateEmail(to: emailTextField.text!) { error in
if let error = error {
print(error)
} else {
self.userDocRef = self.db.collection("users").document(self.auth.currentUser!.uid)
self.userDocRef?.getDocument(completion: {(snapshot, error) in
guard snapshot != nil else { print("Error:", error!); return }
let userData = snapshot!.data()!
self.emailTextField.text = userData["email"]! as? String
})
print("CHANGED")
}
}
}

Swift Firebase - get current user with document UID to populate list

So I have done this on my android app (and it works), to populate a list with the document names from a collection
db.collection("usersAuth/${FirebaseAuth.getInstance().uid!!}/KitLists")
.addSnapshotListener(EventListener<QuerySnapshot> { value, e ->
if (e != null) {
Log.w("TAG", "Listen failed.", e)
return#EventListener
}
for (document in value.documents) {
val data = document
val kitName = data.id
firstKitList.add(kitName)
}
mainListViewAdapter.notifyDataSetChanged()
})
I am trying to do the same on my iOS version but I don't know whats wrong
override func viewWillAppear(_ animated: Bool) {
setListener()
}
func setListener() {
db.collection("usersAuth/\(String(describing: Auth.auth().currentUser))/KitLists")
.addSnapshotListener { (snapshot, error ) in
if let err = error {
debugPrint("Error fetching docs: \(err)")
} else {
guard let snap = snapshot else {return}
for document in snap.documents {
let data = document.data()
let kitListName = data["KitLists"] as? String
let newLists = KitList(kitListName: kitListName!)
self.lists.append(newLists)
}
self.tableView.reloadData()
}
}
}
any ideas? Thanks
-- EDIT
Firestore
Firestore2
You need to get the uid from the currentUser, for example:
if let userId = Auth.auth().currentUser.uid {
db.collection("usersAuth").document(userId).collection("KitLists")
.addSnapshotListener { (snapshot, error ) in
//...
}
To get the KitLists documentId
for document in snap.documents {
let documentName = document.documentID // <--- This
let newLists = KitList(kitListName: documentName)
self.lists.append(newLists)
}

Add unique values to my array in Parse Server (swift 3)

My Parse Server has a class called "BooksAddedByUser", which has 3 columns:
objectId
user - contains the username of the PFUser.current()
ISBNArray - the ISBN of books added by the user
I would like to add the newly added bookNumber into the ISBNArray only if it doesn't exist in the that array yet. However, whenever I run my code below, it creates new objectIds with the same username in the class "BooksAddedByUser". And it also doesn't check if the bookNumber already exists. I'm not sure what's going on honestly.
let booksAddedByUser = PFObject(className: "BooksAddedByUser")
booksAddedByUser["user"] = PFUser.current()?.username
let query = PFQuery(className: "BooksAddedByUser")
query.whereKey("ISBNArray", contains: bookNumber)
query.findObjectsInBackground { (objects, error) in
if error != nil {
print(error)
} else {
print(self.bookNumber)
if let objects = objects {
for object in objects {
print("book is already added i think")
}
}
}
}
booksAddedByUser.addObjects(from: [bookNumber], forKey: "ISBNArray")
booksAddedByUser.saveInBackground { (success, error) in
if error != nil {
print("error saving new book")
} else {
print("new book saved!")
}
}
EDIT w/ new code:
let booksAddedByUser = PFObject(className: "BooksAddedByUser")
booksAddedByUser["user"] = PFUser.current()?.username
let query = PFQuery(className: "BooksAddedByUser")
query.findObjectsInBackground { (objects, error) in
if error != nil {
print(error)
} else {
print(self.bookNumber)
if let objects = objects {
if objects.contains(bookNumber) {
print("book exists")
}
}
}
}
booksAddedByUser.addObjects(from: [bookNumber], forKey: "ISBNArray")
booksAddedByUser.saveInBackground { (success, error) in
if error != nil {
print("error saving new book")
} else {
print("new book saved!")
}
}
You can check if an object exits in array by using this:
if arrObjects.contains(where: { $0.bookNumberPropertyName == "bookNumber" }) {
print("Book exists")
}

Resources