2017-07-09 13 views
1

スポーツマネージャーアプリを構築して、ユーザーが自分のコンテストを作成し、他の参加者との相談にマッチ結果を更新できるようにします。スポーツマネージャーFirebaseデータベースを構築する方法

私はデータベースのフラット性について多くのことを読んでいます(私はSQLから来ました:-)、そしてFirebaseチームから多くのビデオチュートリアルを見ました。

は、私がこのような構造を持っている。この時点で:

{sport-manager : 
    ... 
    groups : { 
     "groupId1" : { 
      competitionId : "competitionId1" 
      name : "Group A", 
      type : "LEAGUE" 
     }, 
     "groupId2" : { 
      competitionId : "competitionId1" 
      name : "West playoofs", 
      type : "PLAYOFFS" 
     }, 
     ... 
    }, 
    players : { 
     "playerId1" : { 
      birthday : 351408600000, 
      firsName : "Jhon", 
      lastName : "Doe", 
      shirtNumber : 0, 
      teamId : "teamId1" 
     }, 
     ... 
    }, 
    teams : { 
     "teamId1" : { 
      competitionId : "competitionId1" 
      name : "Team 1", 
      }, 
     ... 
    }, 
    teamGroupStats : { 
     "groupId1" : { 
      "teamId1" : { 
       goalsAgainst: 0, 
       goalsFavor: 0, 
       matchesDraw: 0, 
       matchesLoss: 0, 
       matchesPlayed: 0, 
       matchesWin: 0, 
       points: 0, 
       teamName: "Team 1", 
      }, 
      "teamId2" : { 
      ... 
      }, 
      ... 
     }, 
     "groupId2" : { 
      "teamId2" : { 
      ... 
      }, 
      ... 
     } 
     ... 
    } 
} 

この構造では、私は、クエリは、このようにグループの一部である全チームのデータとリストビューアダプタを移入するために作成してみましょう:

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference(); 
Query groupQuery = mDatabase.child("teamGroupStats").child("groupId1") 

または私はdeterminatedチームから選手を取得する必要があります。これまでのところ

Query playersQuery = mDatabase.child("players").orderByChild("teamId").equalTo("teamId1"); 

を、そう 良い。私の問題は、この構造からチームを削除する必要があるときです。整合性の問題を避けるため、私はマルチパスアップデートを使用してすべてを削除します。

  • チームは、チームが1つ以上のグループの一部であることができる1人の以上のプレーヤー
  • を持つことができます。

これを念頭に置いて、すべての選手を含むチームを削除できます。私は「teamId1は、」構造「teamGroupStats」でsecundaryキーを持っていると、すべてのパスを取得するクエリを作成するにはどうすればよい

Map<String, Object> deleteMap = new HashMap<>(); 
deleteMap.put("teams/teamId1", null); 

Query playersQuery = mDatabase.child("players").orderByChild("teamId").equalTo("teamId1"); 
playersQuery.addListenerForSingleValueEvent(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     for (DataSnapshot playerSnapshot : dataSnapshot.getChildren()){ 
      deleteMap.put("players/" + playerSnapshot.getKey(), null); 
     } 

     // Delete all in one call! 
     mDatabase.updateChildren(deleteMap); 
    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) { 

    } 
}); 

? 彼のこの構造は私が必要とする用途に適していますか?

答えて

0

最後に、私は1つの解決策を見つけました。私はチームがチーム構造内に属するすべてのグループIDを格納するようにデータベースを修正しました。

teams : { 
    "teamId1" : { 
     competitionId : "competitionId1" 
     groups : { 
      "groupId1" : true, 
      "groupId6" : true, 
      ... 
     }, 
     name : "Team 1", 
     }, 
    ... 

この情報で、内部のValueEventListenerをplayersQueryのリスナーに追加して、更新/削除を行うことができます。

public static void deleteTeam(final String teamId){ 
    Map<String, Object> deleteMap = new HashMap<>(); 
    deleteMap.put("teams/" + teamId, null); 

    DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference(); 
    Query playersQuery = mDatabase.child("players").orderByChild("teamId").equalTo(teamId); 
    playersQuery.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      for (DataSnapshot playerSnapshot : dataSnapshot.getChildren()){ 
       String playerId = playerSnapshot.getKey(); 
       deleteMap.put("players/" + playerId, null); 
      } 

      mDatabase.child("teams").child(teamId).child("groups") 
       .addListenerForSingleValueEvent(new ValueEventListener() { 
       @Override 
       public void onDataChange(DataSnapshot dataSnapshot) { 
        for (DataSnapshot groupSnapshot : dataSnapshot.getChildren()){ 
         String groupId = groupSnapshot.getKey(); 
         deleteMap.put("teamGroupStats/" + groupId + "/" + teamId, null); 
        } 

        // Delete all in one call! 
        mDatabase.updateChildren(deleteMap); 
       } 

       @Override 
       public void onCancelled(DatabaseError databaseError) { 
        System.out.println("The read failed: " + databaseError.getCode()); 
       } 
      }); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
      System.out.println("The read failed: " + databaseError.getCode()); 
     } 
    }); 
} 

私は内側のリスナーについて非常に確認されませんでした、と私は私のデータベース構造に少し変更を加えなければならなかったが、これは正常に動作します。

誰かがこれを行う良い方法を知っていれば、私はそれを読むために開いています。ありがとう!

0

あなたのデータベースは非常にうまく構成されています。あなたの質問に関して、あなたが言うようにすべての道を得ることはできません。何をすることができます、それを追加するのと同じ方法でデータを削除することです。だから私はあなたがこの方法を使用してrecomandすべてのデータを削除するために:

private static void deleteTeam(String teamId) { 
    Map<String, Object> map = new HashMap<>(); 
    map.put("/teams/" + teamId, null); 
    map.put("/teamGroupStats/groupId1/" + teamId, null); 
    map.put("/players/playerId1/teamId/", null); 
    databaseReference.updateChildren(map); 
} 

より一般的な方法は次のようになります。

private static void deleteTeam(String reference, String teamId) { 
    Map<String, Object> map = new HashMap<>(); 
    map.put(reference, null); 
    databaseReference.updateChildren(map); 
} 

あなたは追加のデータを取得するためにデータベースを照会する必要がある場合は、getRef()メソッドを使用します参照を取得し、それらの値を2番目のメソッドに渡します。

すべてのデータは、一度に原子的に削除されます。

希望します。

+0

私は各チームに1人のプレイヤーしかいないという問題は1つのグループにしか存在しません。私はあなたの方法を使用することはできません。なぜなら私は各チームの選手やチームが所属するグループをデータベースに照会するまで知らないからです(そして、非同期呼び出しはそれを助けません)。 –

+0

この場合は、クエリを作成し、必要なデータをすべて見つけてそのデータをメソッドに渡します。私はより一般的な方法で私の答えを更新しました。 –

+0

私はあなたの助けに感謝しますが、その一般的な方法は機能しません。マップ内に「path、null」という1つのペアのみが設定されており、マルチパスの削除は行われません。チームとその投稿に表示されたすべてのプレイヤーを削除する方法はうまくいきますが、私の問題は「チームグループ」から2次キー(チームID)を取得することです。それができないなら、多分私の構造に問題があります。 –

関連する問題