Firebase 如何在一个';onUpdate';云功能?

Firebase 如何在一个';onUpdate';云功能?,firebase,google-cloud-firestore,google-cloud-functions,firebase-admin,onupdate,Firebase,Google Cloud Firestore,Google Cloud Functions,Firebase Admin,Onupdate,我正在尝试创建一个“onUpdate”函数来加载已更新的文档。然后我想使用通配符接收的数据加载另一个文档。因此,为了总结,我想访问更新过的文档以及同一个集合中的另一个文档 我想要:/userProfiles/{doc1}/employees/{doc2}和/userProfiles/{doc1} 我可以同时获得它们,但当我尝试使用其中一个的数据时,它不会读取以前的数据,并给我一个ReferenceError 最终目标是使用这两个文档与NodeEmailer一起发送电子邮件。谢谢你的帮助 常量函

我正在尝试创建一个“onUpdate”函数来加载已更新的文档。然后我想使用通配符接收的数据加载另一个文档。因此,为了总结,我想访问更新过的文档以及同一个集合中的另一个文档

我想要:
/userProfiles/{doc1}/employees/{doc2}
/userProfiles/{doc1}

我可以同时获得它们,但当我尝试使用其中一个的数据时,它不会读取以前的数据,并给我一个
ReferenceError

最终目标是使用这两个文档与NodeEmailer一起发送电子邮件。谢谢你的帮助


常量函数=需要(“firebase函数”);
const admin=require(“firebase管理员”);
const nodemailer=require('nodemailer');
admin.initializeApp();
exports.testLog=functions.firestore
.document('/userProfiles/{doc1}/employees/{doc2}'))
.onUpdate((更改、上下文)=>{
var信息=[];
const doc1=context.params.doc1;
const doc2=context.params.doc2;
const db=admin.firestore();
返回(
分贝
.集合(“用户配置文件”)
.doc(`${doc1}`)
.get()
。然后(doc=>{
var email=doc.data().email;
var phone=doc.data().phone;
信息推送(doc.data());
console.log(电子邮件、电话);//查看并获取信息
回复邮件、电话;
}),
分贝
.集合(“用户配置文件”)
.doc(`${doc1}`)
.collection(`employees`)
.doc(`${doc2}`)
.get()
。然后(doc=>{
信息推送(doc.data());
var Status=doc.data().Status;
log(电话,${Status}`);//电话未定义
如果(`${Status}`==“报警”){
//替换为用户设置页面中的变量
console.log(`${info.phone}`);//电话未定义
让transporter=nodeEmailer.createTransport({
主机:“smtp.gmail.com”,
港口:587,
安全:错误,
认证:{
用户:“xxxxxx@gmail.com",
通行证:“XXXXXXXXX”
}
});
//使用定义的传输对象发送邮件
让邮件选项={

from:“”Fred Foo有两件事并没有按照你预期的方式产生问题:

  • 承诺的处理并没有真正按照您期望的方式传递数据——特别是,变量phone和email只存在于一个承诺处理程序中,它们的作用域不是全局的,因此,
    phone
    email
    不会沿着承诺链传递

  • 实际上,您不需要阅读第二个文档,因为内容是通过函数本身传递给您的。这实际上大大简化了您正在做的全部工作,并且使处理第一点变得几乎微不足道,因为您可以跳过第二个数据库调用

看看这段代码,为了清楚起见,我省略了消息传递代码,只保留了大部分日志消息:

exports.firestoreonUpdate=functions.firestore
.document('/userProfiles/{doc1}/employees/{doc2}'))
.onUpdate((更改、上下文)=>{
//var info=[];我已删除此列表,不需要
const doc1=context.params.doc1;
//无需获取doc2参数,因为我们通过函数调用获得了doc本身。
const doc2content=change.after.data();
const db=admin.firestore();
返回(
分贝
.集合(“用户配置文件”)
.doc(`${doc1}`)
.get()
。然后(doc=>{
常量doc1content=doc.data();
const email=doc1content.email;
const phone=doc1content.phone;
console.log(电子邮件、电话);//查看并获取信息
log(`不需要获取doc2,因为我已经有了它:${JSON.stringify(doc2content)}`);
const Status=doc2content.Status;
console.log(`user的电子邮件仍然是:${email}`);//电子邮件现在已定义
log(电话,${Status});//电话现在已定义
如果(`${Status}`==“报警”){
console.log(`${phone}`);//电话现在已定义
return console.log('将在此处发送消息-忽略代码')
}
控制台日志(状态);
return console.log(“if语句后的im,未触发报警”);
})
.catch(err=>console.error(err))
);
});
在新版本中,我们只存储触发我们的文档中的内容,包括
Status
参数。然后,我们在树中的更高级别获取包含所需内容的文档。一旦返回该文档,我们只需处理它并与doc2中的数据相结合。所有字段现在都已定义(当然,假设数据库对象格式良好)

如果出现明显的日志消息,您的消息代码将被重新插入

最后,我认为现在没有必要使用
info
列表,因此我已将其删除。相反,我建议您在根据现有数据构建消息时构建所需内容。也就是说,您的原始代码没有正确访问它(即,作为列表),并且可能使您更加困惑


最后,由于问题主要集中在未定义的字段上,我还没有讨论Nodemailer模块的使用,但我怀疑您的原始代码可能也不完全正确——因为它既没有从
sendMail()
返回承诺,也没有对该调用执行
wait
(并使整个函数
异步),因此您需要更仔细地研究这一点。

有两件事情没有按照您预期的方式工作,从而导致您的问题:

  • 对承诺的处理并没有真正按照您期望的方式传递数据——特别是电话和电子邮件存在的变量