[database] Firebase에서 모든 노드 데이터를로드하지 않고 노드의 자식 수를 얻는 방법이 있습니까?

자녀 수를 통해 알 수 있습니다

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

그러나 이것이 서버에서 해당 노드의 전체 하위 트리를 가져옵니다. 거대한 목록의 경우 RAM과 대기 시간이 많이 소요되는 것 같습니다. 모든 것을 가져 오지 않고 카운트 (및 / 또는 자식 이름 목록)를 얻는 방법이 있습니까?



답변

당신이 준 코드 스 니펫은 실제로 전체 데이터 세트를로드 한 다음 클라이언트 측에서 계산합니다. 이는 대량의 데이터에 대해 매우 느릴 수 있습니다.

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는 최근 Cloud Functions를 출시했습니다. Cloud Functions를 사용하면 자체 서버를 만들 필요가 없습니다. JavaScript 함수를 작성하여 Firebase에 업로드하면됩니다. Firebase는 이벤트가 발생할 때마다 기능을 트리거합니다.

예를 들어 투표를 계산하려면 다음과 유사한 구조를 만들어야합니다.

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

그런 다음 노드에 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

2018 년 1 월 업데이트

중포 기지 문서는 그래서 대신 변경 event우리가 지금 가지고 changecontext.

주어진 예제 event.data는 정의되지 않은 불평 오류를 발생시킵니다 . 이 패턴이 더 잘 작동하는 것 같습니다.

exports.countPrescriptions = functions.database.ref(`/prescriptions`).onWrite((change, context) => {
    const data = change.after.val();
    const count = Object.keys(data).length;
    return change.after.ref.child('_count').set(count);
});

“`


답변

다른 사람들이 이미 잘 대답 했으므로 게임에서 약간 늦었지만 구현 방법을 알려 드리겠습니다.

이는 Firebase REST APIshallow=true매개 변수를 제공 한다는 사실에 달려 있습니다.

post객체가 있고 각 객체가 여러 개를 가질 수 있다고 가정하십시오 comments.

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

분명히 모든 주석을 가져오고 싶지는 않지만 주석 수만 가져옵니다.

게시물의 키가 있다고 가정하면에 GET요청을
보낼 수 있습니다 https://yourapp.firebaseio.com/posts/[the post key]/comments?shallow=true.

키-값 쌍의 객체를 반환합니다. 각 키는 주석의 키이고 그 값은 true다음 과 같습니다.

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

이 응답의 크기는 동등한 데이터를 요청하는 것보다 훨씬 작으므로 이제 응답에서 키 수를 계산하여 값을 찾을 수 있습니다 (예 : commentCount = Object.keys(result).length).

반환 된 키 수를 계산하고 있기 때문에 문제를 완전히 해결할 수는 없으며 변경 될 때 값을 구독 할 필요는 없지만 반환 된 데이터의 크기를 크게 변경하지 않아도됩니다. 개요.


답변

카운트를 저장 한 후 유효성을 검사하여 적용하십시오. 나는 독특한 투표와 카운트를 계속 유지하기 위해 이것을 해킹했습니다. 그러나 이번에는 제안을 테스트했습니다! (잘라 내기 / 붙여 넣기 오류에도 불구하고!).

여기서 ‘트릭’은 노드 우선 순위 를 투표 수로 사용하는 것입니다.

데이터는 다음과 같습니다

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()"

사용자는 한 번만 투표 할 수 있으며 && 개수는 현재 개수보다 높고 데이터 값은 우선 순위와 동일해야합니다.

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

count (마지막 유권자 수)-투표가 존재해야하며 그 수는 newcount와 같으며 && newcount (우선 순위)는 1 씩만 올라갈 수 있습니다.

  }
}

다른 사용자가 10 표를 추가하는 테스트 스크립트 유효성 검사에 실패하면 (i–) 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>

여기서 ‘위험’은 투표가 진행되었지만 카운트가 업데이트되지 않은 것입니다 (학킹 또는 스크립트 실패). 그렇기 때문에 투표에 고유 한 ‘우선 순위’가 있습니다. 스크립트는 실제로 현재 순위보다 우선 순위가 높은 투표가 없는지 확인하여 시작해야합니다. 당신을 위해 🙂

시작하기 전에 우선 순위로 카운트를 초기화해야합니다. 위조를 통해이를 수행 할 수 없으므로 유효성 검사가 활성화되기 전에 스텁 스크립트가 필요합니다.


답변

클라우드 함수를 작성하고 노드 수를 업데이트하십시오.

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

루트-| | -users (이 노드에는 모든 사용자 목록이 포함되어 있음) |
| -count | -userscount : (이 노드는 사용자 수와 함께 클라우드 기능에 의해 동적으로 추가됨)


답변