Search code examples
javascriptfirebasegoogle-cloud-functionsgoogle-cloud-scheduler

Firebase - Cloud Functions: TypeError x is not a function


I have a Cloud Function set up with a Cloud Scheduler. Sometimes, when the function is executed, it returns an error message in the logs :

Exception from a finished function: TypeError: newMatches.forEach is not a function

It is returned randomly, most of the time the function works well.

Here is my function :

const db = getFirestore();
const functions = require("firebase-functions");

exports.getAllMatches = functions
    .region("europe-west1")
    .runWith({failurePolicy: true})
    .pubsub.schedule("*/1 * * * *")
    .onRun(async (context) => {

      const rlMatchesToAdd = [];

      /**
       * Function to fetch RL Matches
       * return an array of matches
      */
      async function getNewRLMatches() {
        const rlUrl = "https://apiURL";

        const rlResponse = await fetch(rlUrl);

        const newRLMatches = await rlResponse.json();
        return newRLMatches;
      }

      getNewRLMatches().then((newMatches) => {
        newMatches.forEach((newMatch) => {
          const dateNow = new Date();
          const dateModified = new Date(newMatch["modified_at"]);
          const diff = dateNow - dateModified;
          const newMatchID = newMatch["id"].toString();
          if (diff < 180e3) {
            newMatch["added_at"] = FieldValue.serverTimestamp();
            rlMatchesToAdd
                .push(db.collection("RL Matches")
                    .doc(newMatchID)
                    .set(newMatch));
          }
        });
        const arrLength = rlMatchesToAdd.length;
        if (arrLength === 0) {
          console.log("No RL match have been rencently modified");
        } else {
          console.log(arrLength, " RL matches have been rencently modified");
        }
        uploadMatches(rlMatchesToAdd);
      });

      /**
       * Function to upload matches
       * @param {Object[]} arrMatchesToAdd containing docs to set as parameter
       * return a Promise
      */
      async function uploadMatches(arrMatchesToAdd) {
        return Promise.all(arrMatchesToAdd).then(() => {
          console.log("Write succeeded !");
        });
      }

    });

I've seen some other questions about the same problem, but I can't resolve mine with the answers I've found.

Also, it's my first try in JavaScript and Cloud Functions


Solution

  • It seems that the API is at times not returning an array.

    I recommend checking whether the result you get back from the API matches the requirements of your code, and logging it if it doesn't. Something like:

    if (newMatches && newMatches.forEach) { 
      ... your existing code ... 
    } 
    else { 
      console.error("Did not get an array back: "+JSON.stringify(newMatches)); 
    }