2015-01-10 4 views
4

저는 Firebase를 사용하여 사용자의 일부 데이터를 검색하고 있습니다. 사용자 (gameSearching = true) 한 명만 검색해야합니다. 이 코드를 실행하는거야파이어베이스가 인덱스가 정의되지 않았습니다.

Users 
| 
|_____ John 
|  |___ name: John Farmer 
|  |___ gameSearching: true 
| 
|_____ James 
|  |___ name: James Smith 
|  |___ gameSearching: false 
| 
|_____ Barbara 
     |___ name: Barbara Smith 
     |___ gameSearching: true 

: 같은

내 데이터가 보인다 '데이터'여러 값을 가지고 있기 때문에

setData(('Users/' + you + '/'), {gameSearching: true}); 

var ref = new Firebase("https://grootproject.firebaseio.com/Users"); 
var child = ref.orderByChild("gameSearching"); 
child.on("child_added", function (data) { 
    var yourself = firebase.getAuth().password.email.split("@", 1)[0]; 
    data.forEach(
     function (childSnapshot) { 
      if (childSnapshot[i].val().gameSearching == true && childSnapshot[i].key() != yourself) { 
       var opponent = childSnapshot[i].key(); 

       setData(('Users/' + opponent + '/'), {gameSearching: false}); 
       setData(('Users/' + yourself + '/'), {gameSearching: false}); 
      } 
     } 
    ); 


}); 

, 내가 그들을 분리하는 'data.forEach'를 사용합니다. 그 시점 이후에 나는 'true'에 'return'을 설정할 수 있으므로 'gameSearching : true'로 한 명의 사용자 만 수신합니다.

내 중포 기지 규칙 :

{ 
    "rules": { 
    ".read": true, 
    ".write": true, 
    ".indexOn": "gameSearching" 
    } 
} 

나는 다음과 같은 오류 얻을이 코드를 실행하면 :

'Uncaught Error: No index defined for gameSearching'

내가 'gameSearching'에 인덱스를 설정 검색 한 '.indexOn'를 사용을하지만, 어떤 succes도 아닙니다. https://www.firebase.com/docs/security/guide/indexing-data.html

누구나 예제가 있습니까?


편집 :

이제 다음과 같은 코드를 가지고

:

{ 
"rules": { 
    ".read": true, 
    ".write": true, 
    "Users": { 
    ".indexOn": "gameSearching" 
} 
} 

}

indexOn 오류 :

var ref = new Firebase("https://grootproject.firebaseio.com/Users"); 
    ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1).on("child_added", function (data) { 
     var yourself = firebase.getAuth().password.email.split("@", 1)[0]; 

      var opponent = data.key(); 
      console.log(opponent); 

      setData(('Users/' + opponent + '/'), {gameSearching: false}); 
      setData(('Users/' + yourself + '/'), {gameSearching: false}); 
      console.log('ja'); 
    }); 

내가 내 중포 기지 내 규칙을 편집을 더 이상 보여주지 않을 것이다. 훌륭합니다. 그러나 ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1)는 두 번 실행됩니다. 나는 그게 가능하다는 것을 모른다. 나는 limitToFirst (1)`을 사용하고 있습니다. 그래서 1 명의 자식을 기대합니까?

+0

"어떤 문제도 없다"는 것은 무엇을 의미합니까? 나는 많은 인덱스를 추가했으며 항상 문제없이 작동합니다. 규칙의 관련 섹션을 보여줄 수 있습니까? (질문 아래에있는 편집 링크를 클릭하여 정보를 추가하십시오 ** 주석에 넣지 마십시오 **) –

+0

명령은 위에서 입력 한 것처럼'.indexOf'가 아니라'.indexOn'입니다. 규칙에서 동일한 오타를 만든 경우 실제로 작동하지 않습니다. –

+0

.indexOn, 죄송합니다. 내가 가진 문제는 .indexOn을 어디에 둘지 모르겠다는 것입니다. –

답변

13

이제 규칙을 추가 했으므로 규칙이 잘못되었음을 알 수 있습니다.

{ 
    "rules": { 
    ".read": true, 
    ".write": true, 
    ".indexOn": "gameSearching" 
    } 
} 

그래서 당신은 모든 사람들이 읽고 전체 중포 기지에 대한 액세스를 작성하고 gameSearching에 인덱스를 추가하도록 지시 할 수 :

현재 규칙입니다. 문제는 Firebase에 있어야하는 레벨이 아니라 최상위 레벨에서 인덱스를 정의했다는 것입니다.

이 현재 데이터 구조입니다 :

{ 
    "Score" : { 
     "sam_lous" : { 
      "score" : 2 
     } 
    }, 
    "Users" : { 
     "hallo" : { 
      "gameSearching" : true 
     }, 
     "sam_lous" : { 
      "gameSearching" : true 
     }, 
     "test" : { 
      "gameSearching" : false 
     }, 
     "test2" : { 
      "gameSearching" : true 
     } 
    } 
} 

gameSearching 재산 만 Users 노드의 아이에서 존재한다. 사용자가 정의 할 위치 그래서 당신의 .indexOn : 그와

{ 
    "rules": { 
    ".read": true, 
    ".write": true, 
    "Users": { 
     ".indexOn": "gameSearching" 
    } 
    } 
} 

, 색인이 작성되어야합니다 (내 경험은 바로 당신이 당신의 규칙을 저장할 때 발생) 및 에러/경고 메시지가 사라집니다. 하지만 그 행동을 고치기 위해서, 당신은 또한 내가 다른 대답에 넣었던 변화를 만들어야합니다.

Firebase's documentation on indexing your data은이 .indexOn 규칙을 정의한 위치에서 더 명확하게 나타납니다. Firebase의 누군가가 함께 읽고 있다면, 데이터가있는 수준에서 .indexOn을 정의해야한다는 것을 강조하는 더 좋은 예제를 추가 할 수 있습니까?

+0

Thx Frank van Puffelen! 너 나 많이 도와 줬어! –

+0

인덱스가 실제로 '사용자'아래에서 한 단계 더 깊어 야합니까? 그것이 Firebase의 문서화를 해석하는 방법입니다. – pixelfreak

+0

아니요, 필자는이 예제를 필자의 예제에 넣어야합니다. 링크 된 문서 페이지와 거기에있는 데이터를 확인하십시오 : 구조체는'/ dinosaurs/$ dinosaur/height'이고'height'와'length'에 대한'.indexOn'은 ** dinostaurs입니다 ** ** 만약 당신이 자신의 유스 케이스에서 올바른 색인을 생성하는 데 문제가있는 경우 새 질문을 열고 데이터 샘플 및 보안 규칙을 포함하십시오. –

3

쿼리는 데이터를 주문하지만 필터링하지 못합니다. 이로 변경하는 경우, 쿼리는 게임을 검색하는 사용자를 일치합니다 :

var query = ref.orderByChild("gameSearching").equalTo(true); 

을이 대략 당신이 당신의 이전 질문에 묻는 것입니다 WHERE gameSearching = true의 SQL로 변환합니다. 데이터에 대한 쿼리를 나타내므로 변수 query을 호출했습니다. 또는 SQL 메타포를 사용하려는 경우 관계형 데이터베이스의 VIEW와 더 유사합니다.

child_added을 들으므로 사용자의 쿼리에 맞는 사용자마다 함수가 한 번 호출됩니다. 따라서 forEach은 귀하의 발췌 문장에서 저에게 어떤 의미가 없습니다.

var searchers = ref.orderByChild("gameSearching").equalTo(true); 
searchers.on('value', function(searchersSnapshot) { 
    searchersSnapshot.forEach(function(snapshot) { 
     console.log(snapshot.key()); 
    }); 
}); 

현재 중포 기지에이 기록됩니다 : 당신이 forEach를 사용하려는 경우에는 value 이벤트에 한 번 쿼리와 일치하는 모든 사용자를 얻을 수 있습니다

hallo

sam_lous

test2

당신 또한 child_added을 사용하여 동일한 작업을 수행 할 수 있지만,이 경우에는 forEach이 필요하지 않습니다.

var searchers = ref.orderByChild("gameSearching").equalTo(true); 
searchers.on('child_added', function(snapshot) { 
    console.log(snapshot.key()); 
}); 

재미있는 사실 : on('child_added'은 누락 된 색인의 Firebase 경고를 유발하지만, on('value'은 그렇지 않습니다. 그러나 두 가지 방법 중 하나는 플레이어를 추가 할 때 퍼포먼스가 용인 될 수 없기 때문에 실제로 인덱스를 추가해야한다는 것입니다. -의 5

var searchers = ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1); 

이 다른 많은 작업 2 항에 설명되어 있습니다 :

당신이 단 하나의 아이를 필요로 나타 내기 때문에, 당신은 또한 당신에게 첫 번째 자식을 얻었다 추가 쿼리를 제한 할 수 있습니다 Firebase Web Guide.

관련 문제