Javascript 如何在执行Firebase事务时检查节点的值?
我正在特定位置运行Firebase事务,但在更新它之前,我需要确保它不大于特定数字。如何在Node.JS中执行此操作?我现在的代码不起作用 我的尝试代码:Javascript 如何在执行Firebase事务时检查节点的值?,javascript,node.js,firebase,firebase-realtime-database,Javascript,Node.js,Firebase,Firebase Realtime Database,我正在特定位置运行Firebase事务,但在更新它之前,我需要确保它不大于特定数字。如何在Node.JS中执行此操作?我现在的代码不起作用 我的尝试代码: var reward_count_red_ref = admin .database() .ref("Rewards/" + Artcall_ID + "/" + reward_id + "/rewards_left"); reward_count_red_ref .transaction(current => {
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
布尔值,以查看事务是否确实更改了某些内容。在您的情况下,如果committed
为false
,您希望通知用户票证不可用
还请注意,当前
可能是null
(并且将在事务的大多数第一次运行中)。您可能希望以不同的方式处理该情况,并检查是否存在snapshot.exists()
缺少的另一件事是catch
子句。很可能是你的交易失败了。如果有,你可能会错过它。返回.set(…)
调用也是一个很好的计划,以确保您也能捕获该结果
另一件可能出错的事情是,其他一些代码正在使用set
或update
修改该位置的数据。如果发生这种情况,交易将被取消
至于事务本身中的代码,它看起来很正常。不过,当前的| | 0没有多大意义。如果当前值为null
且ticket\u count
为正数(我认为您在另一个地方有一个守卫),它将永远不会到达该分支
我个人会将(当前| | 0)+增量
更改为当前-票数
,以使其更具可读性,但这只是味道
更新 您可以像这样访问
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}`)
}
}
ref.transaction(…)。然后({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}`)
}
}
带重试的异步函数(ref,事务,尝试=0){
试一试{
const result=await ref.transaction(事务,未定义,false)
返回结果
}捕获(e){
如果(尝试次数<最大交易次数\u尝试次数)返回重试次数(参考,交易,尝试次数+1)
抛出新错误(`transaction failed${MAX\u transaction\u ATTEMPTS}次,错误:${e.message}`)
}
}
您编写的代码缺少一些帮助您调试问题并使其正确运行的成分
事务返回具有两个参数的对象:{committed,snapshot}
。您必须检查committed
布尔值,以查看事务是否确实更改了某些内容。在您的情况下,如果committed
为false
,您希望通知用户票证不可用
还请注意,当前
可能是null
(并且将在事务的大多数第一次运行中)。您可能希望以不同的方式处理该情况,并检查是否存在snapshot.exists()
缺少的另一件事是catch
子句。很可能是你的交易失败了。如果有,你可能会错过它。返回.set(…)
调用也是一个很好的计划,以确保您也能捕获该结果
另一件可能出错的事情是,其他一些代码正在使用set
或update
修改该位置的数据。如果发生这种情况,交易将被取消
至于事务本身中的代码,它看起来很正常。不过,当前的| | 0没有多大意义。如果当前值为null
且ticket\u count
为正数(我认为您在另一个地方有一个守卫),它将永远不会到达该分支
我个人会将(当前| | 0)+增量
更改为当前-票数
,以使其更具可读性,但这只是味道
更新 您可以像这样访问
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}`)
}
}
ref.transaction(…)。然后({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}`)
}
}
带重试的异步函数(ref,事务,尝试=0){
试一试{
const result=await ref.transaction(事务,未定义,false)
返回结果
}捕获(e){
如果(尝试次数<最大交易次数\u尝试次数)返回重试次数(参考,交易,尝试次数+1)
抛出新错误(`transaction failed${MAX\u transaction\u ATTEMPTS}次,错误:${e.message}`)
}
}
只需将条件添加到当前的中即可:
if (current > value) {
return { name: { first: 'Ada', last: 'Lovelace' } };
} else {
return; // Abort the transaction.
}
只需将条件添加到当前
:
if (current > value) {
return { name: { first: 'Ada', last: 'Lovelace' } };
} else {
return; // Abort the transaction.
}
你能更详细地解释一下这些论点的来龙去脉吗?我正在检查文件,却找不到!此外,如果交易被取消,我如何重新启动该方法?@ArjunRam我更新了我的答案。至于文档,请查看事务文档的底部(其中说明返回):感谢您的帮助!你能更详细地解释一下这些论点的来龙去脉吗?我正在检查文件,却找不到!此外,如果交易被取消,我如何重新启动该方法?@ArjunRam我更新了我的答案。至于文档,请查看事务文档的底部(其中说明返回):感谢您的帮助!嘿,我试过了。JSON对象得到更新,但如果我编写命令return current-ticket\u count,它就不起作用了!为什么?嘿,我试过了。JSON对象得到更新,但如果我编写命令return current-ticket\u count,它就不起作用了!为什么?