Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Increment counter with Cloud Functions for Firebase

I have seen an increment counter with Cloud Functions referencing Realtime Database, but not Firebase Firestore yet.

I have a cloud function that listens for new documents:

exports.addToChainCount = functions.firestore
    .document('chains/{name}')
    .onCreate((snap, context) => {

    // Initialize document
    var chainCounterRef = db.collection('counters').doc('chains');

    var transaction = db.runTransaction(t => {
        return t.get(chainCounterRef).then(doc => {
            // Add to the chain count
            var newCount = doc.data().count + 1;
            t.update(chainCounterRef, { count: newCount });
        });
    }).then(result => {
        console.log('Transaction success!');
    }).catch(err => {
        console.log('Transaction failure:', err);
    });
    return true;
});

I'm attempting the above transaction, but when I run firebase deploy in terminal I get this error:

error Each then() should return a value or throw promise/always-return functions predeploy error: Command terminated with non-zero exit code1

This is my first attempt at anything node.js, and I'm not sure I've written this right.

like image 466
Austin Berenyi Avatar asked Jun 25 '18 04:06

Austin Berenyi


People also ask

How do I increment a value in firestore?

Firestore now has a specific operator for this called FieldValue. increment() . By applying this operator to a field, the value of that field can be incremented (or decremented) as a single operation on the server.

Does firebase scale automatically?

Lastly, it'll scale massively and automatically. Firebase Functions will just do it automatically for you based on the traffic you receive and at an incredibly low cost.

Does firebase have Webhooks?

Firebase Webhooks automates the workflow for companies and Developers by triggering the defined events via URL. Firebase Webhooks Integration is the simplest and most efficient way to communicate between app and Firebase.

How does increment work in Firebase?

Let’s take a look at how it works… Increment is a special value that will atomically update a counter based on the interval you specify. You do not need to read the document to obtain the current total - Firebase does all the calculation serverside. In most cases, you will be keeping a count by adding an integer of 1 to the current total.

How do realtime counters work in Cloud Firestore?

Many realtime apps have documents that act as counters. For example, you might count 'likes' on a post, or 'favorites' of a specific item. In Cloud Firestore, you can only update a single document about once per second, which might be too low for some high-traffic applications.

How do I get the current count in Firebase?

You do not need to read the document to obtain the current total - Firebase does all the calculation serverside. In most cases, you will be keeping a count by adding an integer of 1 to the current total. We can decrement a counter by simply changing the interval value to -1.

How can Firebase help you accelerate app development?

Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register Many realtime apps have documents that act as counters. For example, you might count 'likes' on a post, or 'favorites' of a specific item.


2 Answers

There is now a much simpler way to increment/decrement a field in a document: FieldValue.increment(). Your sample would be something like this:

const FieldValue = require('firebase-admin').firestore.FieldValue;
var chainCounterRef = db.collection('counters').doc('chains');
chainCounterRef.update({ count: FieldValue.increment(1) });

See:

  • Incrementing Values Atomically with Cloud Firestore
like image 141
Frank van Puffelen Avatar answered Oct 13 '22 15:10

Frank van Puffelen


If you want to safely increment a number in a document, you can use a transaction. The following code is taken directly from the linked page. It adds one to a field called population in a document /cities/SF after giving it some initial values:

// Initialize document
var cityRef = db.collection('cities').doc('SF');
var setCity = cityRef.set({
  name: 'San Francisco',
  state: 'CA',
  country: 'USA',
  capital: false,
  population: 860000
});

var transaction = db.runTransaction(t => {
  return t.get(cityRef)
      .then(doc => {
        // Add one person to the city population
        var newPopulation = doc.data().population + 1;
        t.update(cityRef, { population: newPopulation });
      });
}).then(result => {
  console.log('Transaction success!');
}).catch(err => {
  console.log('Transaction failure:', err);
});

Bear in mind that Firestore is limited to one write per second under sustained load, so if you're going to be writing a lot, you will need to use a sharded counter instead.

like image 25
Doug Stevenson Avatar answered Oct 13 '22 14:10

Doug Stevenson