Programming

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

procodes 2020. 7. 14. 21:23
반응형

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": {
     ...  
   }
  }
 }
}

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

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

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

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

The size of this response is much smaller than requesting the 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, as you are still calculating the number of keys returned, and you can't necessarily subscribe to the value as it changes, but it does greatly reduce the size of the returned data without requiring any changes to your schema.


Save the count as you go - and use validation to enforce it. I hacked this together - for keeping a count of unique votes and counts which keeps coming up!. But this time I have tested my suggestion! (notwithstanding cut/paste errors!).

The 'trick' here is to use the node priority to as the vote count...

The data is:

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

user can only vote once && count must be one higher than current count && data value must be same as priority.

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

count (last voter really) - vote must exist and its count equal newcount, && newcount (priority) can only go up by one.

  }
}

Test script to add 10 votes by different users (for this example, id's faked, should user auth.uid in production). Count down by (i--) 10 to see validation fail.

<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 a vote is cast, but the count not updated (haking or script failure). This is why the votes have a unique 'priority' - the script should really start by ensuring that there is no vote with priority higher than the current count, if there is it should complete that transaction before doing its own - get your clients to clean up for you :)

The count needs to be initialised with a priority before you start - forge doesn't let you do this, so a stub script is needed (before the validation is active!).


write a cloud function to and update the node count.

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

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

root--| |-users ( this node contains all users list) |
|-count |-userscount : (this node added dynamically by cloud function with the user count)

참고URL : https://stackoverflow.com/questions/15148803/in-firebase-is-there-a-way-to-get-the-number-of-children-of-a-node-without-load

반응형