2016-09-22 3 views
0

firebase를 사용하여 Turn 기반 게임을 개발 중입니다. 내 게임에는 게임 방이 있고 각 방에는 최대 3 개의 하위 노드가 있습니다. 이들은 Player1, Player2 및 현재 사용자 수입니다. 필자의 경우, Player1은 2 개의 자식 노드 (Player1 ID 및 현재 사용자 수)가있는 공간을 만들었습니다. 플레이어 1은 단 한 명의 적을 기다리고 있습니다. 그러나 다른 2 명의 플레이어가 동시에 참여를 클릭하면 방에 3 명의 플레이어가 생깁니다. 어떻게 보안 규칙을 사용하여이 상황을 피할 수 있습니까? 텍스트 아래 같은Firebase (Swift)에서 보안 규칙을 사용하여 하위 노드를 제한하는 방법

내 관련 데이터베이스 부분 :

"QuickPlay3hanePlaying" : { 
"ByVmFbUC6HS01v4SASeA2ev33zz1" : { 
    "3s6TdUxImrNhMReJbS8kBh4I9im1" : { 
    "IQ" : 1350, 
    "date" : 1.474527951467337E9, 
    "gizliSayi" : [ 1, 2, 3, 4, 5 ], 
    "isReady" : 0, 
    "isSiraBende" : 0, 
    "isWin" : 0, 
    "name" : "Emre Esen", 
    "photoUrl" : "https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/1796656_10203231676898828_1482882234_n.jpg?oh=b1600006284e4e8ca9411d804c5571a2&oe=5880E580", 
    "sonTahminim" : [ 1, 2, 3, 4, 5 ], 
    "uid" : "3s6TdUxImrNhMReJbS8kBh4I9im1" 
    }, 
    "ByVmFbUC6HS01v4SASeA2ev33zz1" : { 
    "IQ" : 1280, 
    "date" : 1.474527943420204E9, 
    "gizliSayi" : [ 1, 2, 3, 4, 5 ], 
    "isReady" : 0, 
    "isSiraBende" : 1, 
    "isWin" : 0, 
    "name" : "Emot Emot", 
    "photoUrl" : "https://scontent.xx.fbcdn.net/v/t1.0-1/p200x200/14225541_330456493965915_6052582248934611374_n.jpg?oh=35c26a6ea69a3266451a33908c7a060a&oe=586E13B1", 
    "sonTahminim" : [ 1, 2, 3, 4, 5 ], 
    "uid" : "ByVmFbUC6HS01v4SASeA2ev33zz1" 
    }, 
    "userSayisi" : 2 
} 

}

만들기 룸 코드 블록 :

func createRoom(){ 


    Model.sharedInstance.QuickPlayOdaAdi = Model.sharedInstance.userFirebaseID 

    setPlayerInfo() 

    let interval = NSDate().timeIntervalSince1970 

    let info = ["photoUrl":Model.sharedInstance.userPictureUrl, 
       "uid":Model.sharedInstance.userFirebaseID, 
       "IQ":Model.sharedInstance.userIQ, 
       "name":Model.sharedInstance.username, 
       "isSiraBende":1, 
       "gizliSayi":Model.sharedInstance.gizliSayi, 
       "isReady":Model.sharedInstance.isReadyForPlaying, 
       "isWin":Model.sharedInstance.isWin, 
       "sonTahminim":Model.sharedInstance.rakipSonTahmini, 
       "date":interval] 


    Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.userFirebaseID).setValue(["userSayisi":1]) 

    Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.userFirebaseID).child(Model.sharedInstance.userFirebaseID).setValue(info) 

    // uygulama kapatıldıgında remove olsun diye 

    Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).child(Model.sharedInstance.userFirebaseID).onDisconnectRemoveValue() 
    Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).child("userSayisi").onDisconnectRemoveValue() 



    Model.sharedInstance.handleCreateRoom = Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).observeEventType(.Value, withBlock: { (snapshot) in 

     print("SnapCount: \(snapshot.childrenCount)") 

     // usersayısı ve 1 kullanıcı ile snap sayısı 2 oluyor 1 kullanıcı için 

     if snapshot.childrenCount == 3 { 

      print("Game Start") 




      Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).removeObserverWithHandle(Model.sharedInstance.handleCreateRoom) 

      Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).updateChildValues(["userSayisi":2]) 


      let ilkEleman = snapshot.children.allObjects[0] as! FIRDataSnapshot 

      let ikinciEleman = snapshot.children.allObjects[1] as! FIRDataSnapshot 

      let ucuncuEleman = snapshot.children.allObjects[2] as! FIRDataSnapshot 




      print(ucuncuEleman.key) 

      if ilkEleman.key != Model.sharedInstance.userFirebaseID && ilkEleman.key != "userSayisi" { 

       print(ilkEleman.key) 

       dispatch_async(GlobalBackgroundQueue, { 

        Model.sharedInstance.enemyName = ilkEleman.value!["name"] as! String 
        Model.sharedInstance.enemyIQ = ilkEleman.value!["IQ"] as! Int 
        Model.sharedInstance.enemyFirebaseID = ilkEleman.value!["uid"] as! String 
        Model.sharedInstance.enemyPictureUrl = ilkEleman.value!["photoUrl"] as! String 



      Model.sharedInstance.quickPlayChooseGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["isPlay":1]) 




        dispatch_async(GlobalMainQueue, { 

         self.enemyNameLbl.text = Model.sharedInstance.enemyName 
         self.enemyRank.text = "\(Model.sharedInstance.enemyIQ)" 
         self.enemyImage.hnk_setImageFromURL(NSURL(string: Model.sharedInstance.enemyPictureUrl)!) 


        }) 

       }) 




       Model.sharedInstance.delay(2.5, closure: { 
        self.performSegueWithIdentifier(Model.sharedInstance.quickPlayHaneSayisi, sender: self) 



       }) 




      } 
      else if ikinciEleman.key != Model.sharedInstance.userFirebaseID && ikinciEleman.key != "userSayisi" { 


       print(ikinciEleman.key) 
       dispatch_async(GlobalBackgroundQueue, { 

        Model.sharedInstance.enemyName = ikinciEleman.value!["name"] as! String 
        Model.sharedInstance.enemyIQ = ikinciEleman.value!["IQ"] as! Int 
        Model.sharedInstance.enemyFirebaseID = ikinciEleman.value!["uid"] as! String 
        Model.sharedInstance.enemyPictureUrl = ikinciEleman.value!["photoUrl"] as! String 



        Model.sharedInstance.quickPlayChooseGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["isPlay":1]) 



        dispatch_async(GlobalMainQueue, { 

         self.enemyNameLbl.text = Model.sharedInstance.enemyName 
         self.enemyRank.text = "\(Model.sharedInstance.enemyIQ)" 
         self.enemyImage.hnk_setImageFromURL(NSURL(string: Model.sharedInstance.enemyPictureUrl)!) 


        }) 

       }) 



       Model.sharedInstance.delay(2.5, closure: { 
        self.performSegueWithIdentifier(Model.sharedInstance.quickPlayHaneSayisi, sender: self) 


       }) 

      }else{ 


       print(ikinciEleman.key) 
       dispatch_async(GlobalBackgroundQueue, { 

        Model.sharedInstance.enemyName = ucuncuEleman.value!["name"] as! String 
        Model.sharedInstance.enemyIQ = ucuncuEleman.value!["IQ"] as! Int 
        Model.sharedInstance.enemyFirebaseID = ucuncuEleman.value!["uid"] as! String 
        Model.sharedInstance.enemyPictureUrl = ucuncuEleman.value!["photoUrl"] as! String 



        Model.sharedInstance.quickPlayChooseGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["isPlay":1]) 



        dispatch_async(GlobalMainQueue, { 

         self.enemyNameLbl.text = Model.sharedInstance.enemyName 
         self.enemyRank.text = "\(Model.sharedInstance.enemyIQ)" 
         self.enemyImage.hnk_setImageFromURL(NSURL(string: Model.sharedInstance.enemyPictureUrl)!) 


        }) 

       }) 



       Model.sharedInstance.delay(2.5, closure: { 
        self.performSegueWithIdentifier(Model.sharedInstance.quickPlayHaneSayisi, sender: self) 


       }) 


      } 




     }else if snapshot.childrenCount == 2 { 

      print("1 user waiting") 

      Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["userSayisi":1]) 

     } 



    }) { (error) in 
     print(error) 
    } 


} 

가입 룸 코드 블록 :

func joinRoom(){ 

    setPlayerInfo() 



    Model.sharedInstance.quickPlayRoomPerGameRef.queryOrderedByChild("userSayisi").queryEqualToValue(1).queryLimitedToLast(1).observeSingleEventOfType(.Value, withBlock: { (snapshot) in 



     if snapshot.exists(){ 




     let odaAdi = snapshot.children.allObjects[0] as! FIRDataSnapshot 


     Model.sharedInstance.QuickPlayOdaAdi = odaAdi.key 

     let interval = NSDate().timeIntervalSince1970 

     let info = ["photoUrl":Model.sharedInstance.userPictureUrl, 
      "uid":Model.sharedInstance.userFirebaseID, 
      "IQ":Model.sharedInstance.userIQ, 
      "name":Model.sharedInstance.username, 
      "isSiraBende":0, 
      "gizliSayi":Model.sharedInstance.gizliSayi, 
      "isReady":Model.sharedInstance.isReadyForPlaying, 
      "isWin":Model.sharedInstance.isWin, 
      "sonTahminim":Model.sharedInstance.rakipSonTahmini, 
      "date":interval 
     ] 



     Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).child(Model.sharedInstance.userFirebaseID).setValue(info) 

     Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).removeObserverWithHandle(Model.sharedInstance.handleJoinRoom) 

     Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).child(Model.sharedInstance.userFirebaseID).onDisconnectRemoveValue() 
     Model.sharedInstance.quickPlayRoomPerGameRef.child(Model.sharedInstance.QuickPlayOdaAdi).child("userSayisi").onDisconnectRemoveValue() 



     Model.sharedInstance.quickPlayRoomPerGameRef.child(odaAdi.key).observeSingleEventOfType(.Value, withBlock: { (snapshot) in 

      print("SnapCount: \(snapshot.childrenCount)") 



       let ilkEleman = snapshot.children.allObjects[0] as! FIRDataSnapshot 

       let ikinciEleman = snapshot.children.allObjects[1] as! FIRDataSnapshot 

       let ucuncuEleman = snapshot.children.allObjects[2] as! FIRDataSnapshot 





       if ilkEleman.key != Model.sharedInstance.userFirebaseID && ilkEleman.key != "userSayisi" { 

        print(ilkEleman.key) 

        dispatch_async(GlobalBackgroundQueue, { 

         Model.sharedInstance.enemyName = ilkEleman.value!["name"] as! String 
         Model.sharedInstance.enemyIQ = ilkEleman.value!["IQ"] as! Int 
         Model.sharedInstance.enemyFirebaseID = ilkEleman.value!["uid"] as! String 
         Model.sharedInstance.enemyPictureUrl = ilkEleman.value!["photoUrl"] as! String 



         Model.sharedInstance.quickPlayChooseGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["isPlay":1]) 



         dispatch_async(GlobalMainQueue, { 

          self.enemyNameLbl.text = Model.sharedInstance.enemyName 
          self.enemyRank.text = "\(Model.sharedInstance.enemyIQ)" 
          self.enemyImage.hnk_setImageFromURL(NSURL(string: Model.sharedInstance.enemyPictureUrl)!) 


         }) 

        }) 

        Model.sharedInstance.delay(2.5, closure: { 



         self.performSegueWithIdentifier(Model.sharedInstance.quickPlayHaneSayisi, sender: self) 


        }) 



       } 
       else if ikinciEleman.key != Model.sharedInstance.userFirebaseID && ikinciEleman.key != "userSayisi"{ 


        print(ikinciEleman.key) 
        dispatch_async(GlobalBackgroundQueue, { 

         Model.sharedInstance.enemyName = ikinciEleman.value!["name"] as! String 
         Model.sharedInstance.enemyIQ = ikinciEleman.value!["IQ"] as! Int 
         Model.sharedInstance.enemyFirebaseID = ikinciEleman.value!["uid"] as! String 
         Model.sharedInstance.enemyPictureUrl = ikinciEleman.value!["photoUrl"] as! String 



         Model.sharedInstance.quickPlayChooseGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["isPlay":1]) 


         dispatch_async(GlobalMainQueue, { 

          self.enemyNameLbl.text = Model.sharedInstance.enemyName 
          self.enemyRank.text = "\(Model.sharedInstance.enemyIQ)" 
          self.enemyImage.hnk_setImageFromURL(NSURL(string: Model.sharedInstance.enemyPictureUrl)!) 


         }) 

        }) 

        Model.sharedInstance.delay(2.5, closure: { 




         self.performSegueWithIdentifier(Model.sharedInstance.quickPlayHaneSayisi, sender: self) 


        }) 

       } 
       else{ 

        print(ucuncuEleman.key) 
        dispatch_async(GlobalBackgroundQueue, { 

         Model.sharedInstance.enemyName = ucuncuEleman.value!["name"] as! String 
         Model.sharedInstance.enemyIQ = ucuncuEleman.value!["IQ"] as! Int 
         Model.sharedInstance.enemyFirebaseID = ucuncuEleman.value!["uid"] as! String 
         Model.sharedInstance.enemyPictureUrl = ucuncuEleman.value!["photoUrl"] as! String 



         Model.sharedInstance.quickPlayChooseGameRef.child(Model.sharedInstance.userFirebaseID).updateChildValues(["isPlay":1]) 


         dispatch_async(GlobalMainQueue, { 

          self.enemyNameLbl.text = Model.sharedInstance.enemyName 
          self.enemyRank.text = "\(Model.sharedInstance.enemyIQ)" 
          self.enemyImage.hnk_setImageFromURL(NSURL(string: Model.sharedInstance.enemyPictureUrl)!) 


         }) 

        }) 

        Model.sharedInstance.delay(2.5, closure: { 




         self.performSegueWithIdentifier(Model.sharedInstance.quickPlayHaneSayisi, sender: self) 


        }) 


       } 







     }) { (error) in 
      print(error) 
     } 




     }else{ 

     self.createRoom() 

     } 


     }) { (error) in 

      print(error) 
    } 

} 
+0

질문에 JSON 트리 그림이 포함되었습니다. 실제 JSON을 텍스트로 바꾸십시오. Firebase 데이터베이스 콘솔에서 내보내기 버튼을 클릭하면 쉽게 얻을 수 있습니다. JSON을 텍스트로 사용하면 검색이 가능해 지므로 실제 데이터로 테스트하고이를 사용하여 쉽게 답변 할 수 있습니다. 일반적으로 할 일은 단지 좋은 일입니다. 이미 시도한 것을 보여주는 코드를 추가하면 도움이 될 것입니다. 비록 당신이 그것을 작동시키지 못한다 할지라도, 당신이 성취하고자하는 것과 당신이 이미 그것을 작동 시키려고 시도했던 것을 명확히합니다. –

+0

@FrankvanPuffelen 귀하의 답변에 대해 제 질문을 업데이트했습니다. –

+0

childCount 조건을 가진'if' 블록을 반복적으로 시도해 보셨습니까? – Dravidian

답변

0

이 가능하다 전자 보안 규칙 내에서 처리 할 수 ​​있지만 데이터베이스 구조를 조금 변경해야합니다. 대신 당신은 지금 무엇을의이 같은 뭔가를해야만 할 필요가 :

"QuickPlay3hanePlaying" : { 
    "ByVmFbUC6HS01v4SASeA2ev33zz1" : { 
    "Player1" : { 
     "3s6TdUxImrNhMReJbS8kBh4I9im1" : { 
     "IQ" : 1350, 
     ... 
     "uid" : "3s6TdUxImrNhMReJbS8kBh4I9im1" 
     }, 
    }, 
    "Player2" : { 
     "ByVmFbUC6HS01v4SASeA2ev33zz1" : { 
     "IQ" : 1280, 
     ... 
     "uid" : "ByVmFbUC6HS01v4SASeA2ev33zz1" 
     }, 
    }, 
    "userSayisi" : 2 
    } 

그리고 보안 규칙은 다음과 같을 것이다 :

{ 
"rules": { 
    "QuickPlay3hanePlaying": { 
    "$id": { 
     "player1": {".validate": true}, 
     "player2":{".validate": true}, 
     "userSayisi": {".validate": true}, 
     "$other": {".validate": false} 
     } 
    } 
    } 
} 

데이터베이스 구조의 변화에 ​​대한 이유가 있기 때문에 당신은 단지 수 특정 위치의 보안 규칙에 1 개의 와일드 카드 키가 있어야합니다.

+0

답변 해 주셔서 감사합니다. player1이 방 만들기 기능을 사용 중입니다. player2가 회의실 기능을 사용 중입니다. 따라서 2 명의 다른 사용자가 동시에 회의실에 참가하면 모든 player2 사용자가 회의실에 참여할 수 있습니다. 제 생각에는 아이 카운트를 비교해야하지만 보안 규칙에서 자식 카운트를 얻을 수는 없습니다. 감사. –

관련 문제