Reputation: 897
I am creating an app that allows users to rate a business from 1 to 5. I am trying to find the average of the ratings to use in my app. So far I am currently only able to see the count with this code.
I am struggling to figure out how to read the all of the rating objects (randomValue: Int). I was thinking it would be best to store them in an array. I am very new to Node so forgive me.
I cannot find anything in the Cloud Functions for Firebase docs about this.
The ratings are stored as follows:
My Code:
exports.scoreOneAverage = functions.database.ref('/ratings_average/{business_uid}/Score_1/{random}')
.onWrite(event => {
const collectionRef = event.data.ref.parent;
const countRef = collectionRef.parent.child('count');
// Return the promise from countRef.transaction() so our function
// waits for this async event to complete before it exits.
return countRef.transaction(current => {
if (event.data.exists() && !event.data.previous.exists()) {
return (current || 0) + 1;
}
else if (!event.data.exists() && event.data.previous.exists()) {
return (current || 0) - 1;
}
}).then(() => {
console.log('Counter updated.');
List ratings = event.data.val();
count = countRef.event.data.val();
if( ratings === null ) {
console.log('No ratings');
}
else {
console.log("The average score is:" + count + ratings );
}
});
});
Upvotes: 0
Views: 947
Reputation: 88
The cloud function event you're triggering should be adjusted slightly to make this work. B
From the docs on cloud functions
Path specifications match all writes that touch a path, including writes that happen anywhere below it. If you set the path for your function as /foo/bar, it matches writes at both of these locations:
/foo/bar
/foo/bar/baz/really/deep/path
So basically, the best way to approach this is likely to listen to writes on this path: /ratings_average/{business_uid}/Score_1
You'll also probably want to take advantage of the fantastic lodash library - it has functions that will help you iterate over a javascript Object. Because your firebase database is structured as a series of nested json (with no notion of arrays), you need to traverse over objects to iterate on any collection of data, like the values at Score_1. Below, I'm using the handy lodash .forOwn() function, and lodash .size() to get the number of scores we're taking an average on
Roughly coded out, an average function would look like this:
// at the top of your file,
import _ from 'lodash';
exports.scoreOneAverage = functions.database.ref('/ratings_average/{business_uid}/Score_1')
.onWrite(event => {
const scores = event.data.val();
const avgSum = 0;
_.forOwn(scores, (scoreKey, scoreValue) => {
avgSum += scoreValue;
});
const avg = avgSum / _.size(scores); // this is your average! Do with it what you like
});
Upvotes: 2