![](/img/trans.png)
[英]Firebase cloud function cannot deploy functions that call a separate local function
[英]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()
錯誤地將其解釋為沒有價值的已解決承諾。 在您的下一個代碼塊中,數組jobs
是undefined
值的數組,而不是您期望的數據。
為了解決這個問題,你應該返回值數組而不是使用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.