我正在从一家在线商店收到关于创建类别的Webhook。以下函数在集合categories
中创建文档
exports.createProductWebhookCategory = functions
.https.onRequest(async (request, response) => {
var category = request.body.product_type;
try {
const categoryRef = admin.firestore().collection("categories").doc(`${category}`);
await categoryRef.set({
name: category,
});
response.status(200).send("Done");
} catch (error) {
console.log(error);
response.status(400).send("Error Cat");
}
});
创建类别后,我将调用API在Webflow中创建一个项。通过返回的承诺,我得到了我想存储在以前创建的文档中的项目Id
我尝试了5个类别(5个webhook(,5个类别中只有1或2个更新。其他文档未更新,并且不包含webflowId字段。更新的内容会随着每次测试运行而变化。有人知道我做错了什么吗?
exports.onCreateCategoryCallback = functions
.runWith({ failurePolicy: true })
.firestore
.document("/categories/{categoryId}")
.onCreate(async (snapshot, context) => {
const cat = snapshot.data();
const docId = context.params.categoryId;
const categoryRef = admin.firestore().collection("categories").doc(docId);
try {
const webflow_item = await webflow.createItem({
collectionId: 'xxx',
fields: {
'name': cat.name,
'_archived': false,
'_draft': false,
},
}, { live: true });
console.log(`ItemId for Cat ${cat.name} is ${webflow_item._id}`);
const doc = await categoryRef.get();
console.log(doc.data());
const res = await categoryRef.update({
webflowId: webflow_item._id
});
console.log(`RES for ${cat.name} is: `, res);
console.log("Function complete for cat: ", cat.name);
} catch (error) {
console.log(error);
throw 'error';
}
});
更新失败和成功的控制台日志如下
ItemId for Cat Coffee is 620fdc8858462f33735c986
{ name: 'Coffee' }
RES for Coffee is: WriteResult {
_writeTime: Timestamp { _seconds: 1645206666, _nanoseconds: 686306000 }
}
Function complete for cat: Coffee
问题很可能来自于您没有正确管理第二个云函数(Firestore触发的函数(的生命周期。
正如你将在关于";JavaScript承诺";在官方的Firebase视频系列中,当所有异步操作完成时,您必须在后台触发的Cloud Function中返回Promise或值。通过这种方式,您可以向云功能平台指示它可以关闭运行您的云功能的实例,并且您还可以避免在异步操作完成之前关闭此实例。
具体来说,有时您的云函数会在异步操作完成之前终止,因为您在代码末尾没有返回Promise或值。其他时候,云功能平台不会立即终止功能,异步操作可以完成。您无法控制这种行为,因此它看起来是一种不稳定的行为,很难理解/调试。
因此,以下的适应应该可以做到(未经测试(:
exports.onCreateCategoryCallback = functions
.runWith({ failurePolicy: true })
.firestore
.document("/categories/{categoryId}")
.onCreate(async (snapshot, context) => {
const cat = snapshot.data();
// const docId = context.params.categoryId;
// const categoryRef = admin.firestore().collection("categories").doc(docId);
// You can replace the two above lines by the following one
const categoryRef = snapshot.ref;
try {
const webflow_item = await webflow.createItem({
collectionId: 'xxx',
fields: {
'name': cat.name,
'_archived': false,
'_draft': false,
},
}, { live: true });
console.log(`ItemId for Cat ${cat.name} is ${webflow_item._id}`);
// Not sure why you have the two next lines?? At this stage doc.data() === snapshot.data()
//const doc = await categoryRef.get();
//console.log(doc.data());
const res = await categoryRef.update({
webflowId: webflow_item._id
});
console.log(`RES for ${cat.name} is: `, res);
console.log("Function complete for cat: ", cat.name);
return null; // <== Here return a value when all the asynchronous operations complete
} catch (error) {
console.log(error);
return null;
}
});
根据上面的注释,在创建类别文档时使用事务的代码如下(同样,我没有测试它(:
exports.createProductWebhookCategory = functions
.https.onRequest(async (request, response) => {
var category = request.body.product_type;
try {
const categoryRef = admin.firestore().collection("categories").doc(`${category}`);
await admin.firestore().runTransaction((transaction) => {
return transaction.get(categoryRef).then((doc) => {
if (!doc.exists) {
transaction.set(categoryRef, {
name: category,
})
}
});
})
response.status(200).send("Done");
} catch (error) {
console.log(error);
response.status(400).send("Error Cat");
}
});