In Firebase, is there a way to get the number of node children without loading all node data?

You can get the baby counter through

firebase_node.once('value', function(snapshot) { alert('Count: ' + snapshot.numChildren()); }); 

But I believe that this retrieves the entire subtree of this node from the server. For huge lists, this seems like random access memory and latency. Is there a way to get an account (and / or list of child names) without extracting all this?

+110
database count firebase
Mar 01 '13 at 1:19
source share
5 answers

The code snippet you provided really loads the entire data set and then considers it on the client side, which can be very slow for large amounts of data.

Currently, Firebase does not have the ability to count children without downloading data, but we plan to add them.

At the moment, one of the solutions is to keep the number of children counter and update it every time you add a new child. You can use the transaction to count items, as in the following tracking codes:

 var upvotesRef = new Firebase('https://docs-examples.firebaseio.com/android/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes'); upvotesRef.transaction(function (current_value) { return (current_value || 0) + 1; }); 

For more information, see https://www.firebase.com/docs/transactions.html.

UPDATE: Firebase has recently released cloud-based features. Cloud functions do not require creating your own Server. You can simply write JavaScript functions and load them into Firebase. Firebase will be responsible for launching functions when an event occurs.

If you want to count the number of votes, for example, you must create a structure like this:

 { "posts" : { "-JRHTHaIs-jNPLXOQivY" : { "upvotes_count":5, "upvotes" : { "userX" : true, "userY" : true, "userZ" : true, ... } } } } 

And then write a javascript function to increase upvotes_count when you write to the upvotes node upvotes .

 const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); exports.countlikes = functions.database.ref('/posts/$postid/upvotes').onWrite(event => { return event.data.ref.parent.child('upvotes_count').set(event.data.numChildren()); }); 

You can read the documentation to find out how to get started with cloud features .

In addition, another example of message counting is here: https://github.com/firebase/functions-samples/blob/master/child-count/functions/index.js

+82
Mar 01 '13 at 2:13
source share

It's a bit late in the game, as several others have already answered well, but I will share how I could implement this.

It depends on the fact that the Firebase REST API offers the shallow=true parameter.

Suppose you have a post object, and each can have several comments :

 { "posts": { "$postKey": { "comments": { ... } } } } 

You obviously do not want to receive all comments, only the number of comments.

Assuming you have a key for the message, you can send a GET request at https://yourapp.firebaseio.com/posts/[the post key]/comments?shallow=true .

This will return an object of a key-value pair, where each key is a comment key, and its value is true :

 { "comment1key": true, "comment2key": true, ..., "comment9999key": true } 

The size of this response is much smaller than the query for equivalent data, and now you can calculate the number of keys in the response to find your value (e.g. commentCount = Object.keys(result).length ).

This may not completely solve your problem, since you still calculate the number of keys returned, and you may not necessarily subscribe to the value when changing it, but it significantly reduces the size of the returned data without requiring any changes to your schema.

+23
Jan 22 '16 at 22:46
source share

Save the account when you go and use validation to enforce it. I hacked it together - by counting unique votes and counts that continue to grow! But this time I tried my offer! (despite cutting / pasting errors!).

The "trick" here is to use node priority as a vote count ...

Data:

vote / $ issueBeingVotedOn / user / $ uniqueIdOfVoter = thisVotesCount, priority = thisVotesCount vote / $ issueBeingVotedOn / count = 'user /' + $ idOfLastVoter, priority = CountofLastVote

 ,"vote": { ".read" : true ,".write" : true ,"$issue" : { "user" : { "$user" : { ".validate" : "!data.exists() && newData.val()==data.parent().parent().child('count').getPriority()+1 && newData.val()==newData.GetPriority()" 

the user can vote only once && & the score should be higher than the current counter && the data value should be the same as the priority.

  } } ,"count" : { ".validate" : "data.parent().child(newData.val()).val()==newData.getPriority() && newData.getPriority()==data.getPriority()+1 " } 

count (the last voter is valid) - a vote must exist, and its score is newcount, && & newcount (priority) can only increase by one.

  } } 

A test script to add 10 votes from different users (for this example, a fake id, should the user auth.uid during production). Count (i--) 10 to see that the check failed.

 <script src='https://cdn.firebase.com/v0/firebase.js'></script> <script> window.fb = new Firebase('https:...vote/iss1/'); window.fb.child('count').once('value', function (dss) { votes = dss.getPriority(); for (var i=1;i<10;i++) vote(dss,i+votes); } ); function vote(dss,count) { var user='user/zz' + count; // replace with auth.id or whatever window.fb.child(user).setWithPriority(count,count); window.fb.child('count').setWithPriority(user,count); } </script> 

The "risk" here is that the vote is taken, but the score is not updated (failure or failure of the script). That's why voices have a unique "priority" - the script should really start with the fact that there is no vote with a priority higher than the current account, if he has to complete this transaction before doing his job - get his clients clear for you :)

Counting must be initialized with priority before you begin - forge does not allow you to do this, so you need a script stub (before validation is active!).

+21
Apr 17 '14 at 12:00
source share

write a cloud function and update the number of nodes.

 // below function to get the given node count. const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); exports.userscount = functions.database.ref('/users/') .onWrite(event => { console.log('users number : ', event.data.numChildren()); return event.data.ref.parent.child('count/users').set(event.data.numChildren()); }); 

See https://firebase.google.com/docs/functions/database-events.

root-- | | -users (this node contains a list of all users) |
| -count | -users count: (this node is dynamically added using a cloud function with the number of users)

+4
Sep 05 '17 at 8:33
source share

I appreciate that this is 2 years from an open-ended question, but as the first Google result, I thought I was updating as I am currently looking for a way to get the number of objects for children. This can be done using

The DataSnapshot.numChildren () method is provided; more information can be found here - Firebase Website

-6
Nov 05 '15 at 9:59
source share



All Articles