簡體   English   中英

參數未傳遞給 firebase 雲函數中的本地函數

[英]Param didn't pass to local function in firebase cloud functions

我有一個 Firebase 雲功能,如下所示:

exports.foo = functions.database
  .ref("/candidates/{jobTrack}/{candidateId}")
  .onCreate((snap, context) => {
    const candidate = snap.val().candidate;
    const jobTrack = context.params.jobTrack;

    const jobsRef = admin.database().ref("jobs");
    return jobsRef
      .child(jobTrack)
      .once("value")
      .then(jobs => {
        const promises = [];

        jobs.forEach(job => {
          promises.push(job.val());
        });

        return Promise.all(promises);
      })
      .then(jobs => {
        return jobs.forEach(job => {
          var percent = getMatchedPercent(candidate, job);
          if (percent >= 0.9) {
            admin
              .database()
              .ref("feeds")
              .child(job.feedId)
              .child("upcomingWeek")
              .push(candidate); // add to team's feed
          }
        });
      })
      .catch(err => {
        console.log("firebase got an error: ", err);
      });
  });

在函數foo ,我調用了一個本地非雲函數 getMatchedPercent ,其定義如下:

const getMatchedPercent = (candidate, job) => {
  console.log("In get percent: ", candidate, job);
  // do something
};

問題是當我在調用getMatchedPercent之前檢查foo job.val()時,我可以看到從job.val()控制台打印的有效數據。 一旦進入getMatchedPercent ,我嘗試打印job ,它抱怨它是undefined

有什么我錯過的嗎? 為什么在調用函數時會丟失job的信息? 謝謝!

您的問題是由以下幾行引起的:

const promises = [];

jobs.forEach(job => {
  promises.push(job.val());
});

return Promise.all(promises);

job.val()返回一個(數據的)對象而不是承諾,因此Promise.all()錯誤地將其解釋為沒有價值的已解決承諾。 在您的下一個代碼塊中,數組jobsundefined值的數組,而不是您期望的數據。

為了解決這個問題,你應該返回值數組而不是使用Promise.all()

const jobValues = [];

jobs.forEach(job => {
  jobValues.push(job.val());
});

return jobValues;

但是因為這里沒有發生異步工作,所以你可以扁平化你的 Promise 鏈。 通過這樣做,您將使用更少的內存,因為您不需要一次包含所有job.val()對象的數組。

exports.foo = functions.database
  .ref("/candidates/{jobTrack}/{candidateId}")
  .onCreate((snap, context) => {
    const candidate = snap.val().candidate;
    const jobTrack = context.params.jobTrack;

    const jobsRef = admin.database().ref("jobs");
    return jobsRef
      .child(jobTrack)
      .once("value")
      .then(jobs => {
        const promises = []; // will contain any team feed update promises

        jobs.forEach(jobSnapshot => { // This is DataSnapshot#forEach
          const job = jobSnapshot.val();
          const percent = getMatchedPercent(candidate, job);
          if (percent >= 0.9) {
            promises.push(
              admin
                .database()
                .ref("feeds")
                .child(job.feedId)
                .child("upcomingWeek")
                .push(candidate) // add to team's feed
            );
          }
        });

        return Promise.all(promises);
      })
      .catch(err => {
        console.log("Failed to update team feeds: ", err);
      });
  });

但是,這仍然存在另一個問題,即某些提要更新可能會成功,而另一些可能會失敗,從而使您的數據庫處於未知狀態。 因此,您可能需要考慮以原子方式寫入數據庫(寫入所有數據,或者什么都不寫入)。

這可以使用以下方法實現:

exports.foo = functions.database
  .ref("/candidates/{jobTrack}/{candidateId}")
  .onCreate((snap, context) => {
    const candidate = snap.val().candidate;
    const jobTrack = context.params.jobTrack;

    const jobsRef = admin.database().ref("jobs");
    return jobsRef
      .child(jobTrack)
      .once("value")
      .then(jobs => {
        const pendingUpdates = {}; // "path: value" pairs to be applied to the database
        const feedsRef = admin.database().ref("feeds");

        jobs.forEach(jobSnapshot => { // This is DataSnapshot#forEach
          const job = jobSnapshot.val();
          const percent = getMatchedPercent(candidate, job);

          if (percent >= 0.9) {
            const pushId = feedsRef.push().key; // push() without arguments doesn't write anything to the database, it just generates a new reference with a push ID we can use.
            const path = job.feedId + "/upcomingWeek/" + pushId;
            pendingUpdates[path] = candidate; // queue add to team's feed
          }
        });

        // apply all updates in pendingUpdates object,
        // relative to feedsRef as an all-or-nothing operation.
        // e.g. pendingUpdates["feed001/upcomingWeek/9jksdfghsdjhn"] = "someUserId"
        //      will be written to "feeds/feed001/upcomingWeek/9jksdfghsdjhn"
        return feedsRef.update(pendingUpdates); // commit changes
      })
      .catch(err => {
        console.log("Failed to apply all feed updates: ", err);
      });
  });

暫無
暫無

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

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