Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore - how to add/subtract from a map of values

I am following the Firestore instructions for storing arrays: https://firebase.google.com/docs/firestore/solutions/arrays

Now what I would like to do is push to this map. For example right now i have:

Contacts
   contact1: true

But I would like to add or remove a contact for example:

Contacts
   contact1: true
   contact2: true

I have tried getting the Contacts map and using the push method but I don't think this will work as it is not a traditional array. For example:

this.afs
  .doc(`groups/${group.id}`)
  .ref.get()
  .then(doc => {
    let contacts: Array<any> = doc.data().contacts;

    contacts.push({ // error here as push is not a function
      [contactId]: true
    });

    console.log(contacts);
  });

Is there an easier way to do this - am I missing something?

like image 769
rhysclay Avatar asked May 10 '18 03:05

rhysclay


People also ask

How do I get distinct values on firestore?

There is no specific API to retrieve unique values from Cloud Firestore. You will have to retrieve all relevant documents and determine the unique names in your own code. Alternatively, consider adding a document with unique names and update that with every write.

How do I add a Subcollection to firestore?

The solution goes: Get the interested document (doc) and then: doc. ref. collection('Collection_Name'). add('Object_to_be_added') It is advisable to include a then/catch after the promise.

How do I add a field to an existing document in firestore?

Build a DocumentReference to the document you want to update, then use the update() method on the DocumentReference to indicate only the fields to be added or changed. Pass it an object with only properties that match the fields to add or change.


2 Answers

Simply push in map

use update() as following

const db = firebase.firestore();
const collection = db.collection('collectionId');

collection.doc(`groups/${group.id}`).update({

      "Contacts.contact3":true

    }).then(function(){

       console.log("Successfully updated!");

});
like image 72
voomin kim Avatar answered Oct 26 '22 11:10

voomin kim


First, you can't use the push method on an object since the map is not an array.

You can simply use the . or [] operators to access/add/update values of a map in JS.

In cases of objects stored in firestore like Arrays and Objects, you can't really directly "push" values to them. You first need to get the document containing them and then update their value locally.

After that is done, you update the value to the Firestore.

To simplify the process, you can use the runTransaction() method provided by Firestore SDK or the Admin SDK if you are on Cloud Functions.

Here's the code which will get the job done for you.

const docRef = this.afs.doc(`groups/${groupId}`);

db.runTransaction((t) => { // db is the firestore instance
  return t.get(docRef).then((doc) => { // getting the document from Firestore
    // {} is a fallback for the case if the "obj" is not present in the firestore
    const obj = doc.get("contacts") ? doc.get("contacts") : {};
    obj[contactId] = true; // updating the value here locally

    t.set(docRef, { contacts: obj }, { // updating the value to Firestore.
      merge: true,
    });

    return;
  }).then((result) => {
    console.log('map updated', result);
    return;
  }).catch((error) => handleError(error));
});
like image 38
Utkarsh Bhatt Avatar answered Oct 26 '22 09:10

Utkarsh Bhatt