Mehul Mali
Mehul Mali

Reputation: 3254

How to create "likes count" Cloud Firestore aggregate function?

I am newb to firebase, I want to create an aggregate function for the likes count.

I have three root collection: feeds, likes, and users.

feeds have the following fields:

enter image description here

description: <description of feed>

likeCount:<Total count of like>

title: <feed title>

userId: <userId of feed>


likes have the following fields:

enter image description here

feedId: <id of the feed where a user gives like>

likeBy: <id of the user who likes the feed>

likeTo: <id of the user how created a feed>


users have the following fields:

username: <User name>

email: <User email>

When a user likes a feed then new entry added in likes collection.

I am trying to create an aggregate function to increase likeCount in feed collection when the user gives like on a feed.


I am checking for a solution. I have found a solution for the nested structure like following

enter image description here


So, my question is that is it possible to create an aggregate function for the likes count with my data structure (three root collection: feeds, likes, and users.)? If yes then How can I achieve it?

or Do I need to change my data structure?

Upvotes: 2

Views: 1951

Answers (2)

Nat
Nat

Reputation: 1812

I have implemented a similar feature in mine, I used Firebase Cloud Functions

So you could do something like this:

Whenever something get's added to the database at a particular location, increment the 'likesCounter' by one:

exports.countLikes = functions.firestore
.document('likes').onWrite((change, context) => {
 const data = change.after.val();
 const count = Object.keys(data).length;
 return change.after.document.collection('likesCount').set(count - 1);
});

^^ You would put that code in the index.js file of your firebase functions project folder.

You'll need to change the code above to fit the data structure of your database. Follow theses steps to get started with cloud functions on your firebase project if you're not familiar.

2023 UPDATE

It is more efficient and less costly to use the admin.firestore.FieldValue.increment() as Runaud said. For example:

exports.countLikes = firebase.firestore.document('likes').onWrite((change, context) => {
    return admin
         .firestore()
         .collection("users")
         .doc(context.userID)
         .update({
            likesCount: admin.firestore.FieldValue.increment(1),
          });
}

Upvotes: 5

Mehul Mali
Mehul Mali

Reputation: 3254

I have achieved my requirement by onCreate() method

following is the code:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();
const db = admin.firestore();

exports.getLikeCount = functions.firestore
    .document('likes/{likeId}')
    .onCreate((snap, context) => {
        // Get an object representing the document (get created like data)
        const likeData = snap.data();

        // Get feed_id from created like data
        const feedId = likeData['feed_id'];

        // Create feed ref from feed_id which get from created like data
        const feedRef = db.collection('feeds').doc(feedId);

        return feedRef
            .get()
            .then(doc => {
                // Get current likesCount for feed
                const likesCount = doc.data().likesCount;

                // Increase likesCount with +1 for get feed
                return feedRef.update({likesCount: likesCount + 1});
            })

    });

Upvotes: 2

Related Questions