在执行Firebase事务时,如何检查节点的值



我正在特定位置运行Firebase事务,但在更新它之前,我需要确保它不大于特定的数字。如何在Node中执行此操作。JS?我现在的代码不起作用。

我尝试的代码:

var reward_count_red_ref = admin
.database()
.ref("Rewards/" + Artcall_ID + "/" + reward_id + "/rewards_left");
reward_count_red_ref
.transaction(current => {
const increment = -1 * ticket_count;
console.log("Going to check if tickets are available");
if (ticket_count > current) {
console.log("Tickets not available. The current value is:", current);
} else {
return (current || 0) + increment;
console.log("They are available. The current value is:  ", current);
}
})
.then(() => {
console.log("Tickets updated.");
admin
.database()
.ref(
"/Reserve_Project_Request/" + Artcall_ID + "/" + User_ID + "/Response"
)
.set("success");
});

您编写的代码缺少一些帮助您调试问题并使其正确运行的成分。

事务返回一个带有两个参数的对象:{ committed, snapshot }。检查committed布尔值以查看事务是否真的发生了更改,这一点非常重要。在您的情况下,如果committedfalse,您希望通知用户票证不可用。

还要注意,current可能是null(并且将出现在事务的大多数第一次运行中(。您可能希望以不同的方式处理这种情况,并检查snapshot.exists()

缺少的另一个内容是catch子句。很可能是你的交易失败了。如果是,您可能会错过它。返回.set(...)调用也是一个很好的计划,以确保您也能得到结果。

另一件可能出错的事情是,其他一些代码正在使用setupdate修改该位置的数据。如果发生这种情况,交易将被取消。

至于事务本身中的代码,它看起来很好。不过current || 0没有多大意义。如果电流是null,而ticket_count是一个正数(我认为你在另一个地方有一个保护(,它永远不会到达这个分支。

我个人会把(current || 0) + increment改成current - ticket_count,让它更可读,但这只是味道。


更新

您可以这样访问committedsnapshot

ref.transaction(...).then(({ committed, snapshot }) => ...)

如果你想重试失败的交易,你可以使用这样的功能:

async function withRetries(ref, transaction, attempts = 0) {
try {
const result = await ref.transaction(transaction, undefined, false)
return result
} catch (e) {
if (attempts < MAX_TRANSACTION_ATTEMPTS) return withRetries(ref, transaction, attempts + 1)
throw new Error(`transaction failed ${MAX_TRANSACTION_ATTEMPTS} times, error: ${e.message}`)
}
}

只需向current:添加条件

if (current > value) {
return { name: { first: 'Ada', last: 'Lovelace' } };
} else {
return; // Abort the transaction.
}

最新更新