В Firebase есть ли способ получить количество дочерних узлов узла без загрузки всех данных узла?

вы можете получить счет ребенка через

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

но я считаю, что это загружает все поддерево этого узла с сервера. Для огромных списков это кажется интенсивным RAM и задержкой. Есть ли способ получить количество (и / или список имен детей) без извлечения всего этого?

5 ответов


фрагмент кода, который вы дали, действительно, загрузить весь набор данных, а затем подсчитывает его на стороне клиента, который может быть очень медленным для больших объемов данных.

Firebase в настоящее время не имеет способа подсчета детей без загрузки данных, но мы планируем добавить его.

сейчас, одним из решений было бы поддерживать счетчик количества детей и обновлять его каждый раз при добавлении нового ребенка. Вы можете использовать транзакцию для подсчета элементов, как в этом отслеживании кода upvodes:

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;
});

дополнительная информация:https://www.firebase.com/docs/transactions.html

обновление: Firebase недавно выпустила облачные функции. С облачными функциями, вам не нужно создавать свой собственный сервер. Вы можете просто написать функции JavaScript и загрузить их в Firebase. Firebase будет отвечать за запуск функций всякий раз, когда происходит событие.

если вы хотите подсчитать upvotes, например, вы должны создать структура, подобная этой:

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

а затем напишите функцию javascript, чтобы увеличить upvotes_count когда есть новая запись в 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());
});

вы можете прочитать документация уметь начало работы с облачными функциями.

кроме того, еще один пример подсчета сообщений здесь: https://github.com/firebase/functions-samples/blob/master/child-count/functions/index.js


это немного поздно в игре, так как несколько других уже ответили красиво, но я расскажу, как я мог бы реализовать его.

это зависит от того, что опорному пункту API-интерфейс REST предлагает


сохранить граф, как вы идете, и использовать проверку на практике. Я взломал это вместе - для сохранения количества уникальных голосов и подсчетов, которые продолжают появляться!. Но на этот раз я проверил свое предложение! (несмотря на ошибки вырезания / вставки!).

"трюк" здесь заключается в использовании узла приоритет как подсчет голосов...

данные:

голосовать / $issueBeingVotedOn / user / $uniqueIdOfVoter = thisVotesCount, priority=thisVotesCount проголосовать / $ 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()" 

пользователь может голосовать только один раз & & count должен быть выше, чем текущий счет & & значение данных должно быть таким же, как приоритет.

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

count (последний избиратель действительно) - голосование должно существовать, и его количество равно newcount, & & newcount (приоритет) может увеличиваться только на один.

  }
}

тестовый скрипт для добавления 10 голосов разными пользователями (для этого примера id подделан, должен ли пользователь auth.жидкость в производство). Отсчет на (Я -) 10 к проверке не.

<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>

"риск" здесь заключается в том, что голосование брошено, но счетчик не обновлен (ошибка haking или скрипта). Вот почему голоса имеют уникальный "приоритет" - скрипт должен действительно начинаться с обеспечения того, что нет голосования с приоритетом выше текущего счета, если есть, он должен завершить эту транзакцию, прежде чем делать свои собственные - получить ваши клиенты, чтобы очистить для вас :)

в count должен быть инициализирован с приоритетом перед запуском-forge не позволяет вам это делать ,поэтому необходим сценарий заглушки (до того, как проверка активна!).


напишите функцию облака и обновите количество узлов.

// 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());
    }); 

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

root--| |-пользователей ( этот узел содержит список всех пользователей ) |
|-рассчитывать / - userscount : (этот узел добавляется динамически облачной функцией с количеством пользователей)


Я ценю, что это 2 года от открытого вопроса, но в качестве первого результата google я думал, что обновлю, поскольку в настоящее время я ищу способ получить количество объектов детей. Это можно сделать с помощью

DataSnapshot.метод numChildren () предоставляется, более подробную информацию можно найти здесь - Сайт Firebase