【发布时间】:2023-03-15 09:37:01
【问题描述】:
我正在尝试编写一个函数,该函数在 Stores/{storeId}/{departmentId}/{productId} 被触发时考虑 3 个条件并在 ref.child('Home').child('Chiep').child(departmentId).child(productId) 中写入新数据。
1) 当firestore 中没有数据时,我需要填写Realtime DB 中的所有字段,方法是依次在firestore 的两个不同节点中查询:Stores 和Products拍摄他们的照片。
2) 当Stores 节点发生更改并且它来自同一个{storeId} 时,我只需要更新一些数据而无需进行任何其他查询。
3) 最后,当Stores 节点发生更改并且来自其他{storeId} 时,我只需要在Stores 节点中进行一次查询。
exports.homeChiepest = functions.firestore
.document('Stores/{storeId}/{departmentId}/{productId}')
.onWrite((change, context) => {
const storeId = context.params.storeId;
const departmentId = context.params.departmentId;
const productId = context.params.productId;
const ref = admin.database().ref();
// Get an object with the current document value.
// If the document does not exist, it has been deleted.
const document = change.after.exists ? change.after.data() : null;
// Get an object with the previous document value (for update or delete)
const oldDocument = change.before.exists ? change.before.data() : null;
// Prevent infinite loops
if (!change.after.exists) {
console.log('DATA DELETED RETURN NULL');
return null;
}
const newPrice = document.price;
const newTimestamp = document.timestamp;
return ref.child('Home').child('Chiep')
.child(departmentId).child(productId)
.once('value')
.then(dataSnapshot => {
if (dataSnapshot.val() !== null) {
console.log('CHIEP DOES exist');
const oldPrice = dataSnapshot.val().price;
const storeKey = dataSnapshot.val().storeKey;
if (storeId === storeKey) {
console.log('SAME STORE - Change price and timestamp');
var newChiepest = {
timestamp: newTimestamp,
price: newPrice
};
return dataSnapshot.ref.update(newChiepest);
} else {
console.log('OTHER STORE - Verify if price is chieper...');
if (newPrice <= oldPrice) {
console.log('NEW PRICE: '+newPrice+' is chieper than the older one: '+oldPrice);
return change.after.ref.parent.parent.get().then(doc => { // HERE Avoid nesting promises
newStoreImg = doc.data().image;
var newStoreChiep = {
price: newPrice,
storeImg: newStoreImg,
storeKey: storeId,
timestamp: newTimestamp
};
return dataSnapshot.ref.update(newStoreChiep);
});
} else {
console.log('NEW PRICE: '+newPrice+' is mode EXPENSIVE than the older one: '+oldPrice);
}
return null;
}
} else {
console.log('data does NOT exist, so WRITE IT!');
let getStoreData = change.after.ref.parent.parent.get();
let getProductData = admin.firestore().collection('Products').doc('Departments').collection(departmentId).doc(productId).get();
return Promise.all([getStoreData, getProductData]).then(values => { // HERE Avoid nesting promises
const [store, product] = values;
var newHomeChiepest = {
depId: departmentId,
price: newPrice,
prodImg: product.data().image,
prodKey: productId,
storeKey: storeId,
storeImg: store.data().image,
timestamp: newTimestamp
};
return dataSnapshot.ref.set(newHomeChiepest);
});
}
})
.catch(error => {
console.log('Catch error reading Home: ',departmentId ,'/', productId,'; message: ',error);
return false;
});
});
问题是:查询或不查询另一个firestore节点的不同可能性导致我在上传Clound Function时出现警告,即:
警告避免嵌套promise promise/no-nesting
感谢您对重构此代码的任何帮助。
【问题讨论】:
-
警告告诉你,像现在这样在另一个
then中使用then被认为是糟糕的风格并且容易出错。你可以重写它。 stackoverflow.com/questions/49844854/… -
停止嵌套 promise 的最简单方法是使用 async/await
-
我同意。我见过的最相似的问题在这里:stackoverflow.com/q/55901953/4300670,但它没有在 IF 语句中查询其他
firebase节点。所以我被卡住了。
标签: javascript firebase promise google-cloud-functions