簡體   English   中英

Firebase pubsub 函數在模擬器中工作,但在生產中不會立即返回

[英]Firebase pubsub function works in emulator but not returns immediatly in production

我的預定功能



// TODO;
export const reportUsage =
  fun.pubsub.schedule("0 0 1 * *").onRun(async (context) => {
    functions.logger.debug("Initialising db");
    const db = admin.firestore();
    const users = await db.collection("users").get();
    users.docs.forEach( async (doc) => {
      functions.logger.debug("Got list of users. Looping..");
      const userData = doc.data();
      const SOME_DATA:number = userData["SOME_DATA"];
      functions.logger.debug("got SOME_DATA of this user");
      const SOME_DATAIntPart:number =
       parseInt(SOME_DATA.toFixed(20).split(".")[0]);
      const SOME_DATAFloatPart:number =
       parseFloat("0." + SOME_DATA.toFixed(20).split(".")[1]);
      const subItemId =
       userData["stripeInfo"]["subscription"]["items"]["data"][0]["id"];
      functions.logger.debug("got sub id of this user");
      await stripe.subscriptionItems.createUsageRecord(subItemId, {
        quantity: SOME_DATAIntPart,
        timestamp: admin.firestore.Timestamp.now().seconds,
      }, {
        timeout: 60,
        maxNetworkRetries: 5,
      });
      functions.logger.debug("got reported to stripe");
      await doc.ref.update({
        "SOME_DATA": SOME_DATAFloatPart,
      });
      functions.logger.debug("updated SOME_DATA");
      return null;
    });
  });

當我從 Cloud Scheduler 手動運行該函數時,它在 Stripe 調用之前返回 RIGHT

 await stripe.subscriptionItems.createUsageRecord(subItemId, {
        quantity: SOME_DATAIntPart,
        timestamp: admin.firestore.Timestamp.now().seconds,
      }, {
        timeout: 60,
        maxNetworkRetries: 5,
      });

我記錄的日志顯示了這一點顯示 Google Cloud 中日志的圖片

如您所見,它在執行 Stripe 調用之前立即返回。

最后一個日志中的錯誤是這樣的: 顯示錯誤日志的圖像

但是,運行函數,firestore 和 pubsub 模擬器,使用函數外殼我可以調用 reportUsage 函數,這就是打印出來的

顯示模擬器中工作日志的圖像

有人可以告訴我為什么 pubsub 功能在生產中不起作用嗎?

您不應在forEach()循環中使用async/await ,請參閱“JavaScript:async/await with forEach()”“Using async/await with a forEach loop”

您可以使用Promise.all()如下:

export const reportUsage = fun.pubsub
  .schedule('0 0 1 * *')
  .onRun(async (context) => {
    functions.logger.debug('Initialising db');

    const db = admin.firestore();
    const users = await db.collection('users').get();

    users.docs.forEach((doc) => {
      functions.logger.debug('Got list of users. Looping..');
      const userData = doc.data();
      const SOME_DATA: number = userData['SOME_DATA'];
      functions.logger.debug('got SOME_DATA of this user');
      const SOME_DATAIntPart: number = parseInt(
        SOME_DATA.toFixed(20).split('.')[0]
      );
      const SOME_DATAFloatPart: number = parseFloat(
        '0.' + SOME_DATA.toFixed(20).split('.')[1]
      );
      const subItemId =
        userData['stripeInfo']['subscription']['items']['data'][0]['id'];
      functions.logger.debug('got sub id of this user');

      const promises = [];
      // We push a Promise to the promsies Array. Note that the then() method returns a promise.
      promises.push(
        stripe.subscriptionItems
          .createUsageRecord(
            subItemId,
            {
              quantity: SOME_DATAIntPart,
              timestamp: admin.firestore.Timestamp.now().seconds,
            },
            {
              timeout: 60,
              maxNetworkRetries: 5,
            }
          )
          .then(() => {
            return doc.ref.update({
              SOME_DATA: SOME_DATAFloatPart,
            });
          })
      );

      functions.logger.debug('updated SOME_DATA');
    });

    await Promise.all(promises);
    return null;
  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM