Reputation: 1999
I'm using Firestore in my application, and I have a map field called "votes" for user's upvotes or downvotes. It looks like this:
I want to add an option to delete an element from there, this is what I got now:
//getting the user's votes dictionary and removing the post from it.
userRef.getDocument { (doc, error) in
if let _ = error { completion(false) }
guard let dict = doc?.data()?[USER_VOTES] as? [String: Any] else { return }
currentDict = dict
currentDict.removeValue(forKey: id)
}
//setting the votes dictionary with the updated one.
userRef.setData(currentDict) { (error) in
if let _ = error { completion(false) }
else { completion(true) }
}
to me, It looks not really efficient, because each time a user is trying to remove an element from this dictionary, I have to write to the database. which can slow down the process and to my understanding, the free tier of Firestore limits the number of writes. Is there a better way, maybe deleting it right from the user's document? I tried to look for answers, but couldn't find anything that worked for me. This one for example: Removing a dictionary element in Firebase looks like what I need to do, but I couldn't get it to work.
EDIT: I tried deleting it like that
userRef.updateData([
USER_VOTES:[
id: FieldValue.delete()
]
]) { (error) in
if let _ = error { completion(false) }
}
The app crashes says:
Terminating app due to uncaught exception 'FIRInvalidArgumentException', reason: 'FieldValue.delete() can only appear at the top level of your update data
Upvotes: 2
Views: 400
Reputation: 1962
To be able to delete a specific field you should follow the steps mentioned here.
For your case I have created the following under collection 'voting':
So to delete vote2 field you should use:
// Get the `FieldValue` object
let FieldValue = require('firebase-admin').firestore.FieldValue;
// Create a document reference
let fieldRef = db.collection('voting').doc('votes');
// Remove the 'vote2' field from the document 'votes'
let removeField = fieldRef.update({
vote2: FieldValue.delete()
});
And here is the document after running the above:
EDIT :
If the data model is a map inside a document, for example:
Then here is how you can delete a field inside the array which is inside the document:
let docRef = db.collection('voting').doc('user1');
let removeField = docRef.set({'votes':
{['id_vote_1'] : FieldValue.delete()}}, {merge: true});
Here is the document after running the above:
Upvotes: 4