0

The "INDEX" sheet is created and has all its data and the sheets titled with the "product code" are created but completely blank. The console log function inside the inner foreach loop does print the data on each iteration but yet the insertRow function wont populate the sheets with the data. Can someone plz tell me what I'm doing wrong.

index.js

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const fs = require('fs-extra')
const gcs = require('@google-cloud/storage')();

const path = require('path');
const os = require('os');

const ExcelJS = require('exceljs');



exports.createCSV = functions.firestore
  .document('reports/{reportId}')
  .onCreate(async (snap, context) => {

    // Step 1. Set main variables
    console.log("Began");
    const reportId = context.params.reportId;
    const fileName = `reports/${reportId}.xlsx`;
    console.log(fileName);
    const tempFilePath = path.join(os.tmpdir(), fileName);

    // Reference report in Firestore
    const db = admin.firestore();
    const reportRef = db.collection('reports').doc(reportId);

    // Reference Storage Bucket
    const storage = gcs.bucket('gs://stock-check-48f78.appspot.com');
    const workbook = new ExcelJS.Workbook();

    // Step 2. Query collection
    try {
      const querySnapshot = await db.collection('stores')
        .get();
      // create array of order data
      const indexWorksheet = workbook.addWorksheet("INDEX");

      querySnapshot.forEach(async doc => {
        //stores.push(doc.data());
        const rowValues = [];
        rowValues[1] = doc.data().code.toString();
        rowValues[2] = doc.data().name;
        rowValues[3] = doc.data().address;
        indexWorksheet.addRow(rowValues);
        const worksheet = workbook.addWorksheet(doc.data().code.toString());
        const storeId = doc.id;
        console.log("Store id is: " + storeId);

        const querySnap = await db.collection('stores').doc(storeId).collection('products').get();

        querySnap.forEach(async a => {
          //console.log(a.data());
          const productValues = [];
          productValues[1] = a.data().name;
          productValues[2] = a.data().packaging;
          productValues[3] = a.data().category;
          productValues[4] = a.data().stock.toString();
          productValues[5] = a.data().order.toString();
          productValues[6] = a.data().last_updated;
          worksheet.insertRow(1, productValues);

        });
      });

      // Step 4. Write the file to cloud function tmp storage
      console.log("Filename is: ");
      console.log(fileName);
      console.log(tempFilePath);
      const buffer = await workbook.xlsx.writeBuffer();
      await fs.outputFile(tempFilePath, buffer);
      console.log("Uploaded");

      // Step 5. Upload the file to Firebase cloud storage
      const file = await storage.upload(tempFilePath, {
        destination: fileName
      });
      console.log("Uploaded to bucket");

      return reportRef.update({
        status: 'complete'
      });

    } catch (err) {
      return console.log(err);
    }

  })


Update I made these changes and still get the same result...(see edited code above)

  • 1
    Your code needs to return a promise that resolves only afer all the async work is complete. Right now, it just returns null, then terminates immediately. When you mix async/await with then/catch, it makes it very hard to trace how the code is running. I strongly recommend only using async/await to make this easier to trace. – Doug Stevenson Jul 02 '20 at 16:53
  • Doug Stevenson is correct, anyway if you are using `async` don't need to use `.then`, just keep using async/await to have cleaner code – Reza Jul 02 '20 at 17:34
  • Thanks for the info guys...but I made some changes as you recommended and still get the same result – Michael Sam Jul 02 '20 at 18:24

1 Answers1

1

Try using promise.all

await Promise.all(querySnap.map(async a => {
      //console.log(a.data());
      const productValues = [];
      productValues[1] = a.data().name;
      productValues[2] = a.data().packaging;
      productValues[3] = a.data().category;
      productValues[4] = a.data().stock.toString();
      productValues[5] = a.data().order.toString();
      productValues[6] = a.data().last_updated;
      worksheet.insertRow(1, productValues);

    }));