Garmaine Staff asked 1 year ago

I am trying to write a function that takes into account 3 conditions whenever Stores/{storeId}/{departmentId}/{productId} gets triggered and write new data in ref.child('Home').child('Chiep').child(departmentId).child(productId).

1) When there is no data in firestore, I need to fill up all the fields in Realtime DB, by making queries in 2 different firestore's nodes: Stores and Products in order to take their images.

2) When a change is made in Stores node and it comes from the same {storeId}, I just need to update some data without making any additional query.

3) And finally, when a change is made in Stores node and it comes from other {storeId}, I need to make only one query in the Stores node.

exports.homeChiepest = functions.firestore
.document('Stores/{storeId}/{departmentId}/{productId}')
.onWrite((change, context) => {

  const storeId = context.params.storeId;
  const departmentId = context.params.departmentId;
  const productId = context.params.productId;
  const ref = admin.database().ref();

  // Get an object with the current document value.
  // If the document does not exist, it has been deleted.
  const document = change.after.exists ? change.after.data() : null;

  // Get an object with the previous document value (for update or delete)
  const oldDocument = change.before.exists ? change.before.data() : null;

  // Prevent infinite loops
  if (!change.after.exists) {
    console.log('DATA DELETED RETURN NULL');
    return null;
  }

  const newPrice = document.price;
  const newTimestamp = document.timestamp;

  return ref.child('Home').child('Chiep')
  .child(departmentId).child(productId)
  .once('value')
  .then(dataSnapshot => {

    if (dataSnapshot.val() !== null) {

      console.log('CHIEP DOES exist');

      const oldPrice = dataSnapshot.val().price;
      const storeKey = dataSnapshot.val().storeKey;
      if (storeId === storeKey) {
        console.log('SAME STORE - Change price and timestamp');
        var newChiepest = {
          timestamp: newTimestamp,
          price: newPrice
        };
        return dataSnapshot.ref.update(newChiepest);

      } else {
        console.log('OTHER STORE - Verify if price is chieper...');
        if (newPrice <= oldPrice) {
          console.log('NEW PRICE: '+newPrice+' is chieper than the older one: '+oldPrice);

          return change.after.ref.parent.parent.get().then(doc => { // HERE Avoid nesting promises
            newStoreImg = doc.data().image;
            var newStoreChiep = {
              price: newPrice,
              storeImg: newStoreImg,
              storeKey: storeId,
              timestamp: newTimestamp
            };
            return dataSnapshot.ref.update(newStoreChiep);

          });

        } else {
          console.log('NEW PRICE: '+newPrice+' is mode EXPENSIVE than the older one: '+oldPrice);
        }
        return null;
      }

    } else {
      console.log('data does NOT exist, so WRITE IT!');

      let getStoreData = change.after.ref.parent.parent.get();
      let getProductData = admin.firestore().collection('Products').doc('Departments').collection(departmentId).doc(productId).get();

      return Promise.all([getStoreData, getProductData]).then(values => { // HERE Avoid nesting promises
        const [store, product] = values;
        var newHomeChiepest = {
          depId: departmentId,
          price: newPrice,
          prodImg: product.data().image,
          prodKey: productId,
          storeKey: storeId,
          storeImg: store.data().image,
          timestamp: newTimestamp
        };
        return dataSnapshot.ref.set(newHomeChiepest);

      });

    }


  })
  .catch(error => {
    console.log('Catch error reading Home: ',departmentId ,'/', productId,'; message: ',error);
    return false;
  });

});

The problem is: different possibilities of querying or not querying another firestore node led me to a warning while uploading the Clound Function, that is:

warning Avoid nesting promises promise/no-nesting

I appreciate any help to refactor this code.