gpt4 book ai didi

javascript - 获取错误 : `Every document read in a transaction must also be written` in Firebase

转载 作者:行者123 更新时间:2023-11-29 18:55:10 25 4
gpt4 key购买 nike

伙计们!

我正在开发一个类似于 https://airtasker.com 的应用程序用户外包任务的地方。任务执行者会对任务出价,并等待用户批准他们的出价。

这些是涉及的集合:

  • 任务
  • 交易
  • 出价

基本上,这个函数应该:

检查是否存在具有给定 taskId 的事务。如果用户开始批准出价,则会添加交易。我允许多个任务者完成任务。

如果交易不存在,它应该添加一个新的,如果达到所需的人力,则将状态标记为正在进行(否则待定),并更新出价集合以标记已接受的出价。

如果交易存在,它应该检查交易集合中当前批准的列表是否等于人力

如果还没有达到配额人力,推送一个新的tasker并访问出价集合以标记出价已接受。

如果在最后一个条件之后,批准的列表已经达到配额人力,则将任务标记为关闭,并将事务状态更改为正在进行

但我不断收到此错误:

Uncaught (in promise) Error: Every document read in a transaction must also be written. at Transaction.commit (transaction.js:128) at eval (sync_engine.js:244)

这是我的代码:

const acceptOffer = async (taskerId, taskId, bidId, offer) => {
let bulk
try {
const taskRef = db.collection('tasks').doc(taskId)
const transRef = db.collection('transactions').doc(taskId)
const bidRef = db.collection('bids').doc(bidId)
const fees = solveFees(offer)

bulk = await db
.runTransaction(async t => {
const transdoc = await t.get(transRef)
const taskdoc = await t.get(taskRef)
const manpower = await taskdoc.get('manpower')

let status = 'pending'
if (manpower === 1) {
status = 'ongoing'
}

if (!transdoc.exists) {
t.set(transRef, {
taskId,
status, // pending, ongoing, completed
approved: [
{ taskerId, ...fees }
]
})

t.update(bidRef, {
accepted: true
})
} else {
const approved = await transdoc.get('approved')
if (manpower < approved.length) {
approved.push({ taskerId, ...fees })
t.update(transRef, { approved })
t.update(bidRef, { accepted: true })

if (manpower === approved.length) {
t.update(taskRef, { open: false })
t.update(transRef, { status: 'ongoing' })
}
}
}
})
} catch (e) {
bulk = e
console.log('nag error', e)
throw e
}

if (bulk.success) {
swal('Offer accepted!', '', 'success')
} else {
swal('Oh, no!',
'This task might already be approved',
'error'
)
}
}

我一直卡在这里,因为我不明白交易失败的地方。很感谢任何形式的帮助。

谢谢!

最佳答案

对于那些遇到同样问题的人,这是我的(hackish)解决方案:

对于每个条件,

添加一个文档写入(可以是 set() update()delete())对应于我代码中读取的每个文档: get() 的使用。

并返回一个 Promise

这是更新后的代码:

// a transaction is added if the user starts to approve offers
// this function allows multiple taskers
const acceptOffer = async (taskerId, taskId, bidId, offer) => {
let bulk
try {
const taskRef = db.collection('tasks').doc(taskId)
const transRef = db.collection('transactions').doc(taskId)
const bidRef = db.collection('bids').doc(bidId)

const fees = solveFees(offer)

bulk = await db
.runTransaction(async t => {
const transdoc = await t.get(transRef)
const taskdoc = await t.get(taskRef)
const manpower = await taskdoc.get('manpower')

// check if a transaction exists with the given taskId
// if it doesn't, then the task doesn't have
// any approved bidders yet
if (!transdoc.exists) {
// check if there is only one manpower required for the task
// mark the status of the transaction 'ongoing' if so
const status = manpower === 1
? 'ongoing' : 'pending'

// add a transaction with the approved tasker
t.set(transRef, {
taskId,
status, // pending, ongoing, completed
approved: [
{ taskerId, ...fees }
]
})

// mark the bid 'accepted'
t.update(bidRef, {
accepted: true
})

// hackish (to prevent firestore transaction errors)
t.update(taskRef, {})

return Promise.resolve(true)
} else { // if a transaction exists with the given taskId
const approved = await transdoc.get('approved')

// check if the current approved list from
// the transactions collection hasn't
// reached the manpower quota yet
if (approved.length < manpower) {
// push new approved bid of the tasker
approved.push({ taskerId, ...fees })
t.update(transRef, { approved })

t.update(bidRef, { accepted: true }) // mark the bid 'accepted'
t.update(taskRef, {}) // hackish

// if, after pushing a new transaction,
// the approved list reached the manpower quota
if (approved.length === manpower) {
t.update(taskRef, { open: false }) // mark the task 'close'
t.update(transRef, { status: 'ongoing' }) // mark the transaction 'ongoing'
t.update(bidRef, {}) // hackish
}
return Promise.resolve(true)
}
return Promise.reject(new Error('Task closed!'))
}
})
} catch (e) {
swal('Oh, no!',
'This task might already be closed',
'error'
)
throw e
}

if (bulk) {
swal('Offer accepted!', '', 'success')
}
}

关于javascript - 获取错误 : `Every document read in a transaction must also be written` in Firebase,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49765422/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com