简体   繁体   中英

Problem to use a Map in Firebase Functions

I am trying to get the length of a Map and I keep getting "undefined". Could please someone tell me what am I doing wrong?

This is the part of the code that gives me problems.

const GYMdetail: { [key: string]: number} = {};
GYMdetail[`${doc.data().name} (${doc.data().personalID})`] = 650;
const subtotal = 650 * GYMdetail.size;

This is the complete function code

export const addGymMonthlyExpense =
  functions.https.onRequest((request, response) => {
    const query1 = admin.firestore().collection("users");
    const query = query1.where("subscriptions.gym.active", "==", true);
    query.get()
        .then(async (allUsers) => {
          allUsers.docs.forEach(async (doc) => {
            if (doc != undefined) {
              const houseForGym = doc.data().subscriptions.gym.house;
              await admin.firestore()
                  .doc(`houses/${houseForGym}/expenses/2022-04`)
                  .get().then((snapshot) => {
                    if (snapshot.data() == undefined) {
                      console.log(`${houseForGym}-${doc.data().name}: CREAR!!`);
                    } else if (snapshot.data()!.issued == false) {

                      let detail: { [key: string]: any} = {};
                      const GYMdetail: { [key: string]: number} = {};
                      detail = snapshot.data()!.detail;
                      GYMdetail[
                          `${doc.data().name} (${doc.data().personalID})`
                      ] = 650;
                      const subtotal = 650 * GYMdetail.size;
                      
                      detail["GYM"] = {"total": subtotal, "detail": GYMdetail};
                      snapshot.ref.set({"detail": detail}, {merge: true});
                    }
                    return null;
                  })
                  .catch((error) => {
                    console.log(
                        `${houseForGym} - ${doc.data().name}: ${error}`);
                    response.status(500).send(error);
                    return null;
                  });
            }
          });
          response.send("i");
        })
        .catch((error) => {
          console.log(error);
          response.status(500).send(error);
        });
  });

Since you are executing an asynchronous call to the database in your code, you need to return a promise from the top-level code; otherwise Cloud Functions may kill the container when the final } executes and by that time the database load won't be done yet.

So:

export const addGymMonthlyExpense =
  functions.https.onRequest((request, response) => {
    const query1 = admin.firestore().collection("users");
    const query = query1.where("subscriptions.gym.active", "==", true);
    return query.get()
      ...

Next you'll need to ensure that all the nested get() calls also get a chance to finish before the Functions container gets terminated. For that I recommend not using await for each nested get call, but a single Promise.all for all of them:

query.get()
    .then(async (allUsers) => {
      const promises = [];
      allUsers.docs.forEach((doc) => {
        const houseForGym = doc.data().subscriptions.gym.house;
        promises.push(admin.firestore()
          .doc(`houses/${houseForGym}/expenses/2022-04`)
          .get().then((snapshot) => {
            ...
          });
      });
      response.send("i");
      return Promise.all(promises);
    })
    .catch((error) => {
      console.log(error);
      response.status(500).send(error);
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM