20

I have a Firebase record "searches: 0" for each user. On some event, I'd like to add 1 to what the current count is. I've gotten this far, but for some reason, it's not working:

du.fbAddSearchCount = function() {
    var usr = new Firebase(firebase_url + "/users/" + user_uid);

    usr.on("value", function(snapshot) {
        user = snapshot.val();

       var usersRef = ref.child("users");

       var fbUser = usersRef.child(user_uid);
       fbUser.update( {
           searches: user.searches + 1
       });
    }
}

Any help to get this working?

Thank you.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
user1661677
  • 1,252
  • 5
  • 17
  • 32

6 Answers6

21

You can use transaction

var databaseRef = firebase.database().ref('users').child(user_uid).child('searches');

databaseRef.transaction(function(searches) {
  if (searches) {
    searches = searches + 1;
  }
  return searches;
});
phd
  • 82,685
  • 13
  • 120
  • 165
Sunday G Akinsete
  • 802
  • 13
  • 14
21

There's a new method ServerValue.increment()in firebase JavaScript SDK v7.14.0

It's better for performance and cheaper since no round trip is required.

See here

Added ServerValue.increment() to support atomic field value increments without transactions.

API Docs here

Usage example:

firebase.database()
    .ref('users')
    .child(user_uid)
    .child('searches')
    .set(firebase.database.ServerValue.increment(1))

Or you can decrement, just put -1 as function arg like so:

firebase.database()
    .ref('users')
    .child(user_uid)
    .child('searches')
    .set(firebase.database.ServerValue.increment(-1))
Olegdater
  • 2,381
  • 22
  • 20
  • 3
    Great update Oleg. There is now indeed also an `increment` operation for the Realtime Database, which performs significantly better than using a transaction (see my test [here](https://stackoverflow.com/questions/61536203/how-quickly-can-you-atomically-increment-a-value-on-the-firebase-realtime-databa)). – Frank van Puffelen May 25 '20 at 00:37
6

For the Realtime Database the use of transaction seems to be the best way to do it. See the answer from Sunday G Akinsete

From his answer and the related comments:

firebase
    .database()
    .ref('users')
    .child(user_uid)
    .child('searches')
    .transaction(function(searches) {
        return (searches || 0) + 1
    })

For the Firestore Database you can use the Firebase Sentinel values to increment/decrement a value that without having to fetch it first

Increment

firebase
    .firestore()
    .collection('users')
    .doc('some-user')
    .update({ 
         valueToIncrement: firebase.firestore.FieldValue.increment(1) 
    })

Decrement

firebase
    .firestore()
    .collection('users')
    .doc('some-user')
    .update({ 
        valueToDecrement: firebase.firestore.FieldValue.increment(-1) 
    })

Documentation Reference

Mathias Gilson
  • 483
  • 1
  • 5
  • 11
4

For the Realtime Database, using increment() works well for this - here's a client-side JS example that uses the newer ESM syntax

import { getDatabase, ref, set, increment } from  "https://www.gstatic.com/firebasejs/9.1.3/firebase-database.js";


// Initialize Firebase
const firebaseConfig = { ...};
const app = initializeApp(firebaseConfig);


const writeFavNameData = name => {
    const db = getDatabase();
    const favRef = ref(db, 'favorites/' + name);
    set(favRef, {
            name,
            likes: increment(1)
    });
};

writeFavNameData("Petunia"); // `likes` is initialized at 1
writeFavNameData("Petunia"); // `likes` is now 2
tonethar
  • 2,112
  • 26
  • 33
  • 1
    Thanks for showing the Firebase 9 syntax. I couldn't find any examples in the docs for how to use increment like this. – Partik Feb 12 '22 at 05:49
0
ref.transection(function(queue_length) {
    if(queue_length|| (queue_length === 0))
    {
        queue_length++; 
    }
    return queue_length;

})

You can use like this ;)

0
database.ref("users").child("user_uid").transaction((user) => {
    if (user) {
        user.searches = actives.searches + 1;
    }
    return user;
});

It works for you. I did that '.child('searches')' but It doesn't work.(nothing changed).

Minwoo Yu
  • 360
  • 2
  • 13