Warm tip: This article is reproduced from stackoverflow.com, please click
firebase google-cloud-firestore javascript

Firestore bulk add field to array

发布于 2020-03-29 12:48:16

I am struggling to add a field to an map in an array. I am trying to add "canAssist": false to each map in the array for each of the countries.

Here is my database:

[
  {
    "Afghanistan": {
      "country": "Afghanistan",
      "countryCode": "AF",
      "countryCodeAlt": "AFG",
      "emoji": "????????",
      "packages": [
        {
          "name": "Luxury Couple",
          "cost": "$2000.00",
          // I want to add canAssist:false here!
        },
        {
          "name": "Quick Retreat",
          "cost": "$1000.00",
          // I want to add canAssist:false here!
        }
      ]
    }
  },
  {...}
  {...}
]

This is what I've tried:

let travelData = database.collection('countries').doc(docName);

travelData.get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(array) {
            packages.map(package => {
                return package.add({
                    canAssist: false
                });
            })
        });
    });
Questioner
aszet
Viewed
61
Juan Vieira 2020-02-03 13:22

You can use Object.values() and object destructuring to achieve this.

    const querySnapshot = [
      {
        Afghanistan: {
          country: 'Afghanistan',
          countryCode: 'AF',
          countryCodeAlt: 'AFG',
          emoji: '????????',
          packages: [
            {
              name: 'Luxury Couple',
              cost: '$2000.00',
              // I want to add canAssist:false here!
            },
            {
              name: 'Quick Retreat',
              cost: '$1000.00',
              // I want to add canAssist:false here!
            },
          ],
        },
      },
      {
        ...
      },
      {
        ...
      },
    ];

    const updateSnapshot = (snapshot, newData) => {
      return snapshot.map(countryData => {
        // only one field with the name of the country
        const country = Object.values(countryData)[0];

        let updatedCountry = { ...country };
        const field = country[newData.field];
        if (field) {
          if (typeof field === 'string') {
            updatedCountry[newData.field] = newData.values;
          } else if (Array.isArray(field)) {
            updatedCountry[newData.field] = field.map(data => ({ ...data, ...newData.values }));
          }
        }
        return { [updatedCountry.country]: updatedCountry };
      });
    };

    (() => {
      console.log('Original', JSON.stringify(querySnapshot, null, 4));
      const updatedSnapshot = updateSnapshot(querySnapshot, { field: 'packages', values: { canAssist: false } });
      console.log('Updated', JSON.stringify(updatedSnapshot, null, 4));
      const updatedSnapshot2 = updateSnapshot(querySnapshot, { field: 'emoji', values: '????????' });
      console.log('Spanish!', JSON.stringify(updatedSnapshot2, null, 4));
    })();

Of course, you don't need to have that dynamism with the 'newData', I just added in case you want to play around any field of your datasource.