如何在React Native中将Firebase Realtime数据库数据值增加1?

时间:2019-05-14 16:10:37

标签: javascript firebase react-native firebase-realtime-database

我有一个像这样的Firebase Realtime数据库。

myRoot |--- mykey1 | |---myValue: 1 | |--- mykey2 | |---myValue: 0 | |--- mykey3 |---myValue: 2

我需要将所有这些值加1并获得以下输出。

myRoot |--- mykey1 | |---myValue: 2 | |--- mykey2 | |---myValue: 1 | |--- mykey3 |---myValue: 3

如何使用循环来做到这一点?或者,在React Native中做到这一点的最佳方法是什么?

我想要的实际东西是这个。假设我有一个主屏幕。它具有一个名为“列表值”的按钮。单击后,我导航到下一页(堆栈导航器),在该页面上显示myKey1,myKey2,myKey3的值。这是一个清单。让我们考虑第二个屏幕中有一个名为“增量值”的按钮。当我按下它时,我想增加值并导航回到主屏幕。

我已经尝试过类似的事情。

let arr = ['myKey1' , 'myKey2' , 'myKey3']

try {
  for(let i=0; i<arr.length; i++) {
     let ref = firebase.database().ref(myRoot).child(arr[i]);
     ref.transaction( function(myValue) {
        return (myValue || 0) + 1;
     })
  }
  this.props.navigation.goBack();
}
catch(error) {
  console.log(error));
}

它按我的预期更改了数据库中的值。但是,执行后会发出以下黄色警告。

  

无法在已卸载的组件上调用setState(或forceUpdate)。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消componentWillUnmount方法中的所有订阅和异步任务

这是一个说明我需要的示例模型。

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

请注意,您每次调用都会调用.then(() => this.props.navigation.goBack());。我认为您需要使用transactions中记录的runTransaction

示例适用于以下结构:

myRoot
  |--- mykey1: number

对于这样的结构:

myRoot
  |--- mykey1
  |     |---myValue: number

您应该改用下一个const ref声明:

const ref = db.ref(myRoot).child(key).child('myValue');

样本Firestore

const arr = ['myKey1' , 'myKey2' , 'myKey3'];
const db = firebase.database();

db.runTransaction(transaction => {
    return Promise.all(arr.map(key => {
      const ref = db.ref(myRoot).child(key);
      return transaction
        .get(ref)
        .then(val => transaction.update(ref, (val || 0) + 1));
    }));
  })
  .then(() => this.props.navigation.goBack())
  .catch((error) => console.log(error))

示例实时数据库

const arr = ['myKey1' , 'myKey2' , 'myKey3'];
const db = firebase.database();

Promise.all(arr.map(key => {
    const ref = db.ref(myRoot).child(key);
    return ref.transaction(function(myValue) {
      return (myValue || 0) + 1;
    })
  }))
  .then(() => this.props.navigation.goBack())
  .catch((error) => console.log(error))