Javascript Param没有';传递给firebase云函数中的局部函数
我有一个firebase云函数,如下所示:Javascript Param没有';传递给firebase云函数中的局部函数,javascript,node.js,firebase,firebase-realtime-database,google-cloud-functions,Javascript,Node.js,Firebase,Firebase Realtime Database,Google 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 = a
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
,我试图打印作业
,它抱怨它的未定义
有什么我错过的吗?为什么调用函数时会丢失
作业
的信息?谢谢 您的问题是由以下几行引起的:
const promises=[];
jobs.forEach(job=>{
promises.push(job.val());
});
返回承诺。全部(承诺);
job.val()
返回的对象(数据)不是承诺,因此promise.all()
错误地将其解释为没有值的已解析承诺。在下一个代码块中,数组jobs
是一个未定义值的数组,而不是预期的数据
要解决此问题,您应该返回值数组,而不是使用Promise.all()
const jobValues=[];
jobs.forEach(job=>{
jobValues.push(job.val());
});
返回作业值;
但是,因为这里没有异步工作,所以您可以扁平化您的承诺链。这样,您将使用更少的内存,因为您不需要一次包含所有job.val()
对象的数组
exports.foo=functions.database
.ref(“/candidates/{jobTrack}/{candidateId}”)
.onCreate((快照,上下文)=>{
const candidate=snap.val().candidate;
const jobTrack=context.params.jobTrack;
const jobsRef=admin.database().ref(“作业”);
返回工作ref
.child(工作轨道)
.一次(“价值”)
.然后(作业=>{
const promissions=[];//将包含任何团队提要更新承诺
jobs.forEach(jobSnapshot=>{//这是DataSnapshot#forEach
const job=jobsnashot.val();
常数百分比=getMatchedPercent(候选人、职务);
如果(百分比>=0.9){
承诺,推动(
管理
.数据库()
.ref(“提要”)
.child(job.feedId)
.儿童(“即将到来的一周”)
.push(候选者)//添加到团队的提要
);
}
});
返回承诺。全部(承诺);
})
.catch(错误=>{
log(“更新团队提要失败:”,错误);
});
});
但是,这仍然存在另一个问题,其中一些提要更新可能成功,而另一些更新可能失败,从而使数据库处于未知状态。因此,您可能需要考虑以原子方式写入数据库(所有数据都是写入的,或者根本没有什么)。
这可以通过以下方式实现:
exports.foo=functions.database
.ref(“/candidates/{jobTrack}/{candidateId}”)
.onCreate((快照,上下文)=>{
const candidate=snap.val().candidate;
const jobTrack=context.params.jobTrack;
const jobsRef=admin.database().ref(“作业”);
返回工作ref
.child(工作轨道)
.一次(“价值”)
.然后(作业=>{
const pendingUpdates={};//“path:value”对将应用于数据库
const feedsRef=admin.database().ref(“提要”);
jobs.forEach(jobSnapshot=>{//这是DataSnapshot#forEach
const job=jobsnashot.val();
常数百分比=getMatchedPercent(候选人、职务);
如果(百分比>=0.9){
const pushId=feedsRef.push().key;//没有参数的push()不会向数据库写入任何内容,它只会生成一个新的引用,其中包含我们可以使用的push ID。
const path=job.feedId+“/upcomingWeek/”+pushId;
pendingUpdates[path]=candidate;//队列添加到团队的提要
}
});
//在PendingUpdate对象中应用所有更新,
//相对于feedsRef,作为全有或全无操作。
//例如,PendingUpdate[“feed001/upcomingWeek/9jksdfghsdjhn”]=“someUserId”
//将写入“feeds/feed001/upcomingWeek/9jksdfghsdjhn”
返回feedsRef.update(PendingUpdate);//提交更改
})
.catch(错误=>{
log(“未能应用所有提要更新:”,错误);
});
});
请注意,您在这里没有正确处理承诺。函数返回null,但实际上它应该返回一个承诺,该承诺在所有异步工作完成时解析。这将是从查询RTDB开始的承诺链。嗯,我将返回设置为jobsRef
,但在getMatchedPercent
函数中仍然得到undefined
。您好@DougStevenson,我根据您在另一个问题中的回答更新了我的代码,但仍然不起作用。我更新了问题中的代码。你能告诉我为什么吗?谢谢谢谢你,山姆!但我尝试了第一种和第二种方法,两种方法都不起作用。在getMatchedPercent
中,它仍然抱怨job
param的undefined
错误。问题是如果job.val()
已经是一个对象,并且我可以从控制台日志中清晰地打印该值,为什么getMatchedPercent
仍然看不到它?