如何处理 firebase 交易中的空值 api

how to handle null values on firebase transaction api

我有一个函数可以通过事务减少用户对 firebase 实时数据库值的信用。 正如 Firebase transaction API call current data is null 中建议的,交易当前值偶尔 returns 为 null。

我已经对 null 情况进行了保护并返回了 0,因此交易函数会再次触发,直到它获得实际信用值。

function charge(cost, description) {
  return new Promise((resolve, reject) => {
    const creditRef = db.ref(`credits/${userid}`)
    ref.transaction(function(current) {
      console.log(`${description} current value: ${current}`)
      if (current === null) {
        console.log(`${description} returns 0 `)
        return 0
      }
      if (cost > current || current === 0) {
        //not enough credits return without committing
        console.log(`${description} aborts `)
        return
      }
      //commit the new credit value
      console.log(`${description} returns ${current} - ${cost}`)
      return current - cost
    },
    (error, commited, snapshot) => {
      if (error) {
        reject(error)
      }
      else {
        if (commited) {
            //user has enough credits
            resolve()
        }
        else {
            //not enough credits
            reject('no commit')
        }
    }
  })
}

但是,在连续触发 2 个充电函数的情况下,第二次调用将获得当前值 0(这可能是第一次充电调用返回的 0)。因此,假设用户没有足够的积分,它将过早退出。当两个函数都解析时,最终信用值将为 3,第二个收费调用将被忽略。

// User has 5 credits 
charge(3, 'first call').then(() => console.log('first call success')
// transaction function returns 0 since current value is null
charge(2, 'second call').then(() => console.log('second call success')

控制台日志输出:

first call current value: null

first call returns 0

second call current value: 0

second call aborts

first call current value: 5

first call returns 5 - 3

first call success

second call no commit

因此,当用户有足够的信用时,第二次收费电话最终无法接通。 处理 firebase 事务空值情况的正确方法是什么?

如果您从数据库中获得 null,则不应进行任何更改。因为你得到 null,所以也 return null.

所以:

const ref = firebase.database().ref(`59571450`)
function charge(cost, description) {
  return new Promise((resolve, reject) => {
    ref.transaction(function(current) {
      console.log(`${description} current value: ${current}`);
      if (current === null) {
        console.log(`${description} returns null`)
        return null;
      }
      if (cost > current) {
        //not enough credits return without committing
        console.log(`${description} aborts `)
        return
      }
      //commit the new credit value
      console.log(`${description} returns ${current} - ${cost}`)
      return current - cost
    },
    (error, commited, snapshot) => {
      if (error) {
        reject(error)
      }
      else {
        if (commited) {
            //user has enough credits
            resolve()
        }
        else {
            //not enough credits
            reject('no commit')
        }
      }
    });
  });
}
                     

ref.set(5).then(() => {
  charge(3, 'first call').then(() => console.log('first call success'))
  charge(2, 'second call').then(() => console.log('second call success'))
})

当 运行 这给出了这个输出:

first call current value: null

first call returns null

second call current value: null

second call returns null

first call current value: 5

first call returns 5 - 3

second call current value: 2

second call returns 2 - 2

first call success

second call success

有关此代码的工作版本,请参阅:https://jsbin.com/xefebul/1/edit?js,console