Reputation: 3254
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:
description: <description of feed>
likeCount:<Total count of like>
title: <feed title>
userId: <userId of feed>
likes have the following fields:
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
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
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
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