0

I'm stuck at trying to get a cloud function to loop over the values of an array in my Cloud Firestore. I have searched stack overflow but I couldn't find a solution yet. My Firestore structure looks as follows:

Image

And my Cloud Function in Jacascript:

exports.createdEnv = functions.firestore.document('environments/{environmentName}')
.onCreate(async snapshot => {

const environmentName = snapshot.id;
const days = db.collection(environmentName);
const batch = db.batch();

        ['2020-02-06', '2020-02-07', '2020-02-08'].forEach((day) => {
        const documentReference = days.doc(day);
        batch.set(documentReference, {});

        //this is where I'm stuck
        const dataMachines = snapshot.data().machineNames;
        for (const value in dataMachines) {
        const valueMachine = dataMachines[value];
        console.log(snapshot.get('machineNames')[0]);
        snapshot.get('machineNames').forEach((value) => {

        //I want each value of the array to be set as subcollection below
        const hoursReference = documentReference.collection(value);
        const dataMap = {   '001': '08:00-09:00',
                            '002': '09:00-10:00',
                            '003': '10:00-11:00',
                            '004': '11:00-12:00',
                            '005': '12:00-13:00',
                            '006': '13:00-14:00',
                            '007': '14:00-15:00',
                            '008': '15:00-16:00',
                            '009': '16:00-17:00',
                            '010': '17:00-18:00',
                            '011': '18:00-19:00',
                            '012': '19:00-20:00',
                            '013': '20:00-21:00',
                            '014': '21:00-22:00',
                                                    };
        Object.keys(dataMap).forEach((hour) => {
            batch.set(hoursReference.doc(hour), {
                hour: dataMap[hour],
                reserved: '',
                name: '',
                date: '',
            });
        });

        });

        }

    });

    return batch.commit()
    .then(() => {console.log('ok'); return null })
    .catch((err) => {console.log(err); });
});

I have been stuck at this for a while and I feel like I'm missing something or forgetting something. If anyone could point me in the right direction that would be great!

  • Could you explain in more detail what you exactly want to do. It is a bit difficult to understand. Firstly, why do you do `batch.set(documentReference, {});` You don't pass any (data) value to `set()`. Secondly, can you give an example of the expected result of your Cloud Function: which documents and collections are created with which content. Thanks! – Renaud Tarnec Feb 06 '20 at 10:15
  • Of course! The function creates a new collection with the environmentName as name. In that collection the function sets 3 documents; 2020-02-06, 2020-02-07, 2020-02-08. Then each of these documents should have subcollections with the names of the values from the array. If I substitute ‘value’ in the hoursReference with a simple string then a subcollection is created without problem. – Lorence Cramwinckel Feb 06 '20 at 10:30

1 Answers1

3

if I have correctly understood your goal, the following should work:

//....
const dataMachines = snapshot.data().machineNames;

dataMachines.forEach(machineName => {

    const hoursReference = documentReference.collection(machineName);

    //....

})

//....

The call to snapshot.data() returns a JavaScript Object in which the machineNames property is an Array. You can check it with console.log(Array.isArray(dataMachines));.

Therefore you just have to use forEach() to get the different values stored in the Array.


Side Note: You will find in the following SO answer several other possible approaches to loop through a JavaScript Array.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121