How to sort Firebase real-time database by the child node with the highest number of

I am working on a database feature that allows users to 'like' comments on posts.

Is there a way for me to sort the comments based on the number of likes they have?

Although I am aware of using .orderByChild(), my issue lies in not having a separate child for the 'like' count.

Currently, I store user UIDs and timestamps within the original commentID child to handle likes.

Would it be feasible to retrieve comments based on the child with the highest number of sub-children?

The structure of my database is as follows:

{
 "users" : {
  "$uid" : {
   "posts" : {
    "$postID" : {
     "postText" : "blah blah blah",
      "comments" : {
       "$commentID" : {
        "commentText" : "blah blah blah",
         "likes" : {
          "UID01" : "1622035190516",
          "UID02" : "1622036141955",
          "UID03" : "1622036145134",
         }
       },
       "$commentID" : {
        "commentText" : "blah 2 blah 2 blah 2",
         "likes" : {
          "UID01" : "1622036141955",
          "UID02" : "1622036145134",
         }
       }
      }
    }
   }
  }
 }
}

Answer №1

Is there a way to retrieve comments based on the child with the highest number of children?

Unfortunately, it is not possible to sort data based on dynamic aggregations.

In the realm of NoSQL databases, a common solution is to maintain a counter. A recommended approach is using a Cloud Function, such as Firebase's Cloud Functions, for backend calculations done via Admin SDK. This allows you to secure the database nodes containing the like counts with appropriate security rules to prevent unauthorized modifications.


Specifically, you should:

1/ Initialize the counter to 1 when the first like is recorded. The following onCreate Cloud Function can be used for this purpose:

exports.initializeCounter = functions.database.ref('users/{uid}/posts/{postID}/comments/{commentID}/likes')
    .onCreate((snapshot, context) => {
      return snapshot.ref.parent.child('nbrOfLikes').set(1);
    });

2/ Update the counter whenever a like is added or removed using an onUpdate Cloud Function that calculates the total likes and updates the counter accordingly. The below Cloud Function demonstrates this process:

exports.updateCounter = functions.database.ref('users/{uid}/posts/{postID}/comments/{commentID}/likes')
    .onUpdate((change, context) => {
        const likeObject = change.after.val();
        return change.after.ref.parent.child('nbrOfLikes').set(Object.keys(likeObject).length);
    });

An alternative method would be utilizing the numChildren() method, as discussed in this answer.


Keep in mind the scenario where all likes are deleted, if applicable in your application.


It is worth noting that the two (or three) Cloud Functions can possibly be consolidated into a single onWrite Cloud Function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Clicking will open the link in both a new tab and the current tab

I'm looking to enable ng click functionality to work in both new tabs and the current tab. The URL is dynamically generated based on a certain condition. Here is the HTML: <a ng-href="{{myPathVariable }} " ng-click=" GoToThemes()" class="shift-l ...

Send form information using AJAX response

I have successfully implemented a feature where I load an iframe into a div with the id of #output using AJAX. This allows me to play videos on my website. jQuery( document ).ready( function( $ ) { $( '.play_next' ).on('click', fun ...

Encountered a discrepancy with npm dependencies during the update or installation process on a legacy project

I am encountering issues while attempting to run an older project. Every time I try to npm install or start the project, it throws various dependency errors, particularly related to the outdated npm version. My current node version is 16.x, whereas the pro ...

Simulating Cordova plugin functionality during unit testing

I have a code snippet that I need to test in my controller: $scope.fbLogin = function() { console.log('Start FB login'); facebookConnectPlugin.login(["public_profile", "email", "user_friends"], FacebookServices.fbLoginSuccess, FacebookServic ...

What is the reason for a type narrowing check on a class property failing when it is assigned to an aliased variable?

Is there a way to restrict the type of property of a class in an aliased conditional expression? Short: I am trying to perform a type narrowing check within a class method, like this._end === null && this._head === null, but I need to assign the r ...

Unable to retrieve custom date picker value with React Antd

I have implemented a custom datepicker for entering dates in the 'MMDD' or 'MMDDYY' format. The date value is stored in state and used in the datepicker component as a controlled component. However, upon form submission, the datepicker ...

Issue with updating bound property correctly when dynamically generating components using v-for in Vue.js

Encountered a challenge with vue.js and seeking guidance on the best approach to address it. Here's a concise summary of the issue: Situation Data is fetched from a rest API, handled by a class called DataLoader using javascript prototype syntax. Th ...

What is the method for eliminating PHP $_SESSION using AJAX?

I am facing an issue with removing an array within a PHP Session variable using AJAX. Here is the process I follow: HTML: <a href="#" onclick="delete_pix(false, '1', false, '1.jpg');">remove</a> JavaScript: functio ...

Encountering an issue with the removal of slides when updating JSON data for angular-flexslider

Issue: Although my JSON object is updating, the slider does not update for all resorts as expected. Sometimes it fails to update when the JSON object changes. The resorts (image collections) that do not update are throwing an error stating "cannot read pr ...

Activate the Masterpage menu to emphasize its current state

I am currently utilizing the AdminLTE template on my website. One issue I have encountered is with the menu and its child menus. When redirecting to different pages using image buttons, the menu collapses back to its original state. While navigating throu ...

Is there a way to convert my function into a variable in order to execute an array of statements

I'm struggling to convert this code into a variable. I need to bind it inside a statement execute array. This is the code I am working on, which retrieves the current date and timezone. I attempted using $date = function() {}, echo $date(); but that ...

ensure that only one option can be selected with the checkbox

Can someone help me with applying this code on VueJS? I tried replacing onclick with @click but it's not working for me. I'm new to VueJS, so any guidance would be appreciated! function onlyOne(checkbox) { var checkboxes = document.getElement ...

Using 'cy.get' to locate elements in Cypress tutorial

Is there a way to search for one element, and if it's not found, search for another element? cy.get(@firstElement).or(@secondElement).click() Can I use a function similar to || in conditions for this scenario? ...

Can a webpage be sent to a particular Chromecast device without using the extension through programming?

My organization has strategically placed multiple Chromecasts across our facility, each dedicated to displaying a different webpage based on its location. Within my database, I maintain a record of the Chromecast names and their corresponding URLs. These d ...

Retrieving and storing information from a form without the need to submit it

I have been given the task of creating a load/save feature for a complex form. The goal is to allow users to save their progress and resume working on it at a later time. After much consideration, I have decided to implement server-side storage by saving ...

How can VueJS manipulate state with Mutation?

I have set up a Vuex Store that returns data on headers and desserts. The desserts object includes a property called display, which is initially set to false. In my project, I am using a component called Row within another component named Table. The Row co ...

Check if an array includes a specific value, and then either update it if found, or create it

I'm currently working with a Cart object in Javascript and I need to check if a specific item is present in the cart. Here's my approach: If the item is already in the cart, update its quantity. If it's not in the cart, add it to the items ...

Execute `preventDefault` prior to authenticating the User with Dev

In my index, I have a modal with a user sign-up form. I created a JavaScript function that triggers when the "Save" button is clicked. If users encounter errors, alerts appear in the modal but it redirects to another page. I want the page to stay on the c ...

Ways to restart script following Ajax call when additional search results are loaded

Implementing Klevu's search results page has been a manageable task so far. However, I encountered an issue where the search results page is displaying an Add to Cart button that should not be there, as confirmed by Klevu themselves. Their suggestion ...

Retrieve the value of the chosen option from a dropdown menu that adjusts dynamically within

I have a query that involves dynamically adding rows to a table for data insertion. A particular <td> element houses a dropdown menu, and I need to extract the selected value from this dropdown in order to make an AJAX call back to a PHP script that ...