Firebase Cloud 函数触发两次 onUpdate
Posted
技术标签:
【中文标题】Firebase Cloud 函数触发两次 onUpdate【英文标题】:Firebase Cloud function triggers twice onUpdate 【发布时间】:2018-01-08 03:30:50 【问题描述】:我为firebase collection - payments
设置了以下规则
"payments":
"$paymentId":
"totalAmount":
,
"balanceAmount":
".validate": "newData.val()<=data.child('totalAmount').val()"
,
"paymentDetails":
"$detailId":
"amount":
".validate": "newData.isString()"
,
,
以及以下为处理该集合的某些更新而编写的云函数:
exports.calculateBalance = functions.database
.ref('payments/pushId')
.onUpdate(event =>
const paymentRef = event.data.adminRef;
const payment = event.data.val();
return paymentRef.once('value').then(snapshot =>
var paidAmount = 0;
snapshot.child("paymentDetails").forEach(function(child)
paidAmount += parseFloat(child.child("amount").val());
);
return paidAmount;
).then(snap =>
payment.balanceAmount = parseFloat(payment.totalAmount) - snap;
return paymentRef.set(payment);
)
);
很简单,每当我添加付款详细信息时,我都想更新balanceAmount
。这里的问题是,每当该集合发生更新时,该函数都会触发两次。第一次从应用程序中显而易见,第二次因为paymentRef.set(payment);
行。
有什么方法可以避免第二次触发云功能吗?我不能在collection
级别上使用任何标志,因为付款详细信息的更新发生了多次。有人可以指导我正确的方向吗?
编辑
注意 - 我有一个输入付款详细信息的编辑选项。
【问题讨论】:
您可以off
删除该节点上的侦听器,然后调用on
再次设置侦听器(我不是一个优秀的Web 开发人员,但我在android 上使用这种方法)
您可以更新付款明细还是直接创建?
【参考方案1】:
如果您只想在添加付款详情时更新余额金额,您可以直接在付款详情上使用 onCreate 触发器。
尝试类似的方法(您必须为您的案例更新代码):
exports.calculateBalance = functions.database.ref('payments/pushId/paymentDetails/detailId').onCreate(event =>
var paymentRef = event.data.adminRef.parent.parent;
var paymentDetailSnapshot = event.data;
var paymentDetailAmountSnapshot = paymentDetailSnapshot.child('amount');
return paymentRef.child('balanceAmount').transaction(current =>
return current - paymentDetailAmountSnapshot.val(); // Balance can be negative
);
);
(使用事务管理并发修改)
Transactions documentation.
注意
请直接为您的金额数据使用数字,而不是字符串。
更新
添加此功能来管理更新:
exports.recalculateBalance = functions.database.ref('payments/pushId/paymentDetails/detailId').onUpdate(event =>
var paymentRef = event.data.adminRef.parent.parent;
var paymentDetailSnapshot = event.data;
var previousPaymentDetailSnapshot = event.data.previous;
var paymentDetailAmountSnapshot = paymentDetailSnapshot.child('amount');
var previousPaymentDetailAmountSnapshot = previousPaymentDetailSnapshot.child('amount');
return paymentRef.child('balanceAmount').transaction(current =>
return current + previousPaymentDetailAmountSnapshot.val() - paymentDetailAmountSnapshot.val(); // Balance can be negative
);
);
【讨论】:
我很欣赏这一点,是的,非常适合,但是应用程序中也有一个编辑选项,所以我怀疑这不会有太大帮助.. :( 给我一点时间..正在检查它.. :) 你提到//余额可以是负数无论如何要克服这个? 这只是一个例子,你可以返回你想要的 好吧..我有点困惑..你能告诉我这是如何避免多次更新的吗?以上是关于Firebase Cloud 函数触发两次 onUpdate的主要内容,如果未能解决你的问题,请参考以下文章
Firebase Cloud Functions 数据库触发器“onCreate 不是函数”
Cloud Functions for Firebase 错误:“400,不允许更改函数触发器类型或事件提供程序”
Cloud Functions for Firebase 的安全 HTTP 触发器