Sennen Randika
Sennen Randika

Reputation: 1636

How to increment Firebase Realtime database data values by one in React Native?

I have a Firebase Realtime database like this.

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

I need to increment all these values by one and get the following output.

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

How I can do this using a loop? Or, what is the best way to do this in React Native?

The actual thing what I want is this. Let's think, I have a home screen. It has a button called "List values". When I clicked, I navigate to the next page (Stack navigator) and there, it displays the values of myKey1, myKey2, myKey3. It is a flatlist. Let's think there is a button called "Increment values" in that second sreen. When I pressed it, I want to increment the values and navigate back to the home screen.

I've tried something like this.

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));
}

It changes the values in the database as I expect. But, it gives the following yellow warning after execution.

Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method

This is a sample model to explain what I need.

How to solve this problem?

Upvotes: 1

Views: 1254

Answers (1)

danpeis
danpeis

Reputation: 166

Notice you are calling to: .then(() => this.props.navigation.goBack()); in each iteration. I think that you need to use a runTransaction as documented in transactions.

Samples are for a structure like:

myRoot
  |--- mykey1: number

For a structure like this:

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

you should use the next const ref declaration instead:

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

Sample 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))

Sample Realtime Database

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))

Upvotes: 1

Related Questions