John Doah
John Doah

Reputation: 1999

Trying to figure out a better way to delete element from Firestore dictionary

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:

enter image description here

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

Answers (1)

Waelmas
Waelmas

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': enter image description here

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: enter image description here

EDIT :

If the data model is a map inside a document, for example: enter image description here

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:

enter image description here

Upvotes: 4

Related Questions