Как получить количество дочерних элементов в защищенной коллекции Firebase?

У меня есть защищенная коллекция firebase для пользователей моего сайта, просто массив пользовательских объектов. Правила разрешений для пользователей разрешают аутентифицированному пользователю доступ только к своему пользовательскому объекту в списке пользователей и ни к кому другому.

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

Любые идеи о том, как это исправить?

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

Я полагаю, что у меня также может быть аутентифицированный наблюдатель на моем сервере, который обходит требование разрешения и отправляет клиенту (либо через firebase, записывая в общедоступное место, либо выставляя его как API) количество пользователей.

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

Спасибо!


person Patrick DeVivo    schedule 11.07.2013    source источник


Ответы (1)


Дублирование данных является нормой в NoSQL, поэтому хранение счетчика вполне разумно. Ознакомьтесь со статьей Firebase об денормализации.

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

Использование счетчика

Это быстро и довольно просто, при условии, что вы используете хорошие принципы DRY и централизуете все свои манипуляции с записями. Используйте транзакцию для обновления счетчика каждый раз, когда запись добавляется или удаляется:

function addUser(user) {
   // do your add stuff...
   updateCounter(1);
}

function removeUser(user) {
   // do your remove stuff...
   updateCounter(-1);
}

function updateCounter(amt) {
   userCounter.transaction(function(currentValue) {
      currentValue || (currentValue === 0); // can be null
      return currentValue + amt;
   });
}

Разделение общедоступных и защищенных данных

Храните конфиденциальные данные (адреса электронной почты, вещи, которые люди не могут видеть) в частном пути, сохраняйте общедоступные пользовательские данные доступными для чтения.

Это предотвращает необходимость синхронизации счетчика. Однако это означает, что клиенты должны загрузить весь список общедоступных пользователей, чтобы создать подсчет. Так что держите общедоступные профили небольшими (имя, метка времени, ничего больше), чтобы он работал с десятками тысяч, не занимая секунд.

"users": {
   ".read": true,
   "$user": {
       // don't try to put a ".read" here; it won't remove access
       // after the parent path allows it
   }
}

"users_secured": {
   "$user": {
       ".read": "auth.id === $user"
   }
}

Использовать серверный процесс

Легко и безболезненно; uber быстро для клиентов, легко обрабатывает сотни тысяч профилей, если у них небольшой размер. Требует, чтобы вы что-то поддерживали. Heroku и Nodejitsu будет размещать это бесплатно до тех пор, пока у вас не появятся пользователи.

var Firebase = require('firebase');

var fb = new Firebase(process.env.FBURL);
fb.auth( process.env.SECRET, function() {
   fb.child('users').on('value', function(snap) {
      fb.child('user_counter').set( snap.numChildren() );
   });
}
person Kato    schedule 18.07.2013