当在子集合reviews
中发布新的review
时,我正试图用事务更新Firestore数据库中restaurant
文档的平均评级。以下代码适用于评论进入缓慢的情况,但如果我在几秒钟内插入10条评论进行压力测试,它将不再正确更新平均评分(即,它可能只计算前5条评论,而不会根据其余评论进行更新(。我对事务的理解是,当数据发生变化时,它会自动重新运行,以确保正确更新值。
这是使用的cloud函数。
exports.reviewCreated = functions.firestore.document('/restaurants/{restaurantid}/reviews/{reviewid}').onCreate((snapshot, context) => {
const rest_id = context.params.restaurantid;
const rest_ref = admin.firestore().collection('restaurants').doc(rest_id)
const rest_rating = snapshot.data().rest_rating;
console.log('The new rest rating is: ' + rest_rating);
try {
admin.firestore().runTransaction((t) => {
return t.get(rest_ref).then((rest_doc) => {
const new_total_reviews = rest_doc.data().totalReviews + 1;
const current_avg_rating = rest_doc.data().averageRating
const new_avg_rating = current_avg_rating + ((rest_rating - current_avg_rating)/new_total_reviews);
t.update(rest_ref, {totalReviews: new_total_reviews,
averageRating: new_avg_rating});
});
})
} catch (e) {
console.log('[Review Created] Transaction Failed', e);
return null;
}
});
测试这个。我在应用程序的调试屏幕上有一个按钮,可以插入虚假评论,代码如下
<Button title = 'Add Review! (Test)'
onPress = {() =>
{
console.log(this.state.uid);
var new_uuid = uuid.v4();
firestore()
.collection('restaurants')
.doc(this.state.restid)
.collection('reviews')
.doc(new_uuid)
.set({
rest_rating: Math.floor(Math.random() * 5) + 1,
review_name: 'test'
});
}}
/>
我是TS的新手,正在尽我所能学习技巧,所以任何阅读/视频都会很有帮助!:(
您没有正确管理云功能的生命周期。正如文档中所解释的;解析执行异步处理的函数(也称为"后台函数"(;。
在您的情况下,您应该返回runTransaction()
方法返回的Promise,如下所示:
exports.reviewCreated = functions.firestore.document('/restaurants/{restaurantid}/reviews/{reviewid}').onCreate((snapshot, context) => {
const rest_id = context.params.restaurantid;
const rest_ref = admin.firestore().collection('restaurants').doc(rest_id)
const rest_rating = snapshot.data().rest_rating;
console.log('The new rest rating is: ' + rest_rating);
return admin.firestore().runTransaction((t) => { // !!! See the return here
return t.get(rest_ref).then((rest_doc) => {
const new_total_reviews = rest_doc.data().totalReviews + 1;
const current_avg_rating = rest_doc.data().averageRating
const new_avg_rating = current_avg_rating + ((rest_rating - current_avg_rating) / new_total_reviews);
t.update(rest_ref, {
totalReviews: new_total_reviews,
averageRating: new_avg_rating
});
});
})
.catch(e => {
console.log('[Review Created] Transaction Failed', e);
return null;
});
});
通过不正确地管理云功能的生命周期,您可能会产生一些";"不稳定";云功能的行为(正如您所提到的"事务并不总是完成"(。
在后台触发的云功能中返回Promise(或值(向云功能平台表明,在Promise实现之前,它不应终止该功能,并避免在异步操作完成之前终止该功能。
所以为什么";事务并不总是完成";很可能是以下情况:有时您的云功能会在异步事务完成之前终止,原因如上所述。其他时候,云功能平台不会立即终止功能,异步交易可以完成(即有可能在云功能终止之前完成(。