lokanath
lokanath

Reputation: 247

How to get the average value from the firebase realtime database

My question is about getting the Avg rating from the database, and then updating the average rating every time a row is added. This is the structure of my database in firebase. Firebase Real-time Database structure

I am trying to retrieve the Average rating of each ID (number like 299536), and update it every time new data/row is added for the same id. I am using Firebase Realtime Database. Any help is appreciated. I am using react.js. Should I create an action for this?

Upvotes: 0

Views: 1586

Answers (3)

user2208124
user2208124

Reputation: 59

You could use a cloud function to do this. Lets use a onCreate listener to average the total each time theres a write.

export const ratingAvg = functions.database
 .ref("ratings/{userId}/{recordId}")
 .onCreate(async (snapshot, context) => {
 const data = snapshot.val(); // rating obj (user, userPhoto, date, comment?, rating)
 const userId = context.params.userId; // this is your userId
 const transactionId = context.params.transactionId; // the uid of the record

 const profileAvg = await admin
  .database()
  .ref(`ratings/${userId}/`)
  .once("value");

  //' if avgRating exists average with new rating else use new rating.
  const newAvg = profileAvg.val().avgRating
  ? ((profileAvg.val().avgRating + data.rating) / 2).toFixed(2)
  : data.rating; 

  // write new average
  return admin
   .database()
   .ref(`ratings/${userId}/`)
   .update({
     avgRating: newAvg
   })
   .then(res => {
     console.log(res);
   })
   .catch(err => {
     console.log(err);
   });
 });

Upvotes: 0

Jack Woodward
Jack Woodward

Reputation: 1001

I would recommend abstracting this logic from your client side as you could have other apps and leaving open the avgRating for anyone to update wouldn't make it trust worthy. You can use a Cloud Function trigger for every rating that is created and run your logic there in a trusted environment and recalculate and update your avgRating Heres a page from the docs that explains creating a function

exports.calculateAvgRating = functions.database.ref('/moveinfo/{moveId}/{rating}')
    .onCreate((snapshot, context) => {
        // LOGIC GOES HERE e.g.
        // Get a list of all your ratings
        // Get average rating
        // Update avgRating
    }

Upvotes: 0

SakoBu
SakoBu

Reputation: 4011

If I understood your question correctly - something like this:

database.ref(`movieinfo/${movieId}/avgRating`)
  .once('value')
  .then((snapshot) => {
    const val = snapshot.val();
    console.log(val);
  })
  .catch((e) => {
    console.log('Error fetching data', e);
  });

Upvotes: 2

Related Questions