2017-05-24 51 views
0

我如何獲得前三名用戶(可能在HashMap中)來自Firebase數據庫中所有用戶的姓名和用戶分數? HashMap必須是order by userScore。或通過userScore得到三個排序用戶的ArrayList<User> usersListdatabase如何從Firebase數據庫中獲取排序數據?

{"top_clicker_db" : { 
    "total_clicks" : 3401, 
    "user" : { 
     "-KkePRVzO_lLLgp7fqX0" : { 
     "name" : "fly", 
     "userScore" : 2000 
     }, 
     "-KkjWk0L2lR8RwUXF2Bd" : { 
     "name" : "lg", 
     "userScore" : 24 
     }, 
     "-KkjjxNw8fj_XG9uUPEg" : { 
     "name" : "fjfg", 
     "userScore" : 304 
     }, 
     "-KkjoakdLIjYlBEM1pkq" : { 
     "name" : "Geny", 
     "userScore" : 100 
     }, 
     "-KklVAOkk2WJaRmH9cKk" : { 
     "name" : "fly", 
     "userScore" : 941 
     } 
    } 
    } 
} 

我需要:

fly=2000; 
fly=941; 
fjfg=304; 

回答

0

我解決了這個問題。但現在我想我怎麼能限制我的list只有3個用戶。

userRef.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       getTopThreeUsers((Map<String, Object>) dataSnapshot.getValue()); 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 
      } 
     }); 

private void getTopThreeUsers(Map<String, Object> users) { 
     HashMap<String, Long> namesAndScores = new HashMap<>(); 
     for (Map.Entry<String, Object> entry : users.entrySet()) { 
      Map singleUser = (Map) entry.getValue(); 
      namesAndScores.put((String) singleUser.get("name"), (Long) singleUser.get("userScore")); 
     } 
     Set<Map.Entry<String, Long>> set = namesAndScores.entrySet(); 
     List<Map.Entry<String, Long>> list = new ArrayList<>(set); 
     Collections.sort(list, new Comparator<Map.Entry<String, Long>>() { 
      public int compare(Map.Entry<String, Long> o1, Map.Entry<String, Long> o2) { 
       return (o2.getValue()).compareTo(o1.getValue()); 
      } 
     }); 

     topName1.setText(list.get(0).getKey()); 
     topName2.setText(list.get(1).getKey()); 
     topName3.setText(list.get(2).getKey()); 

     topScore1.setText(String.valueOf(list.get(0).getValue())); 
     topScore2.setText(String.valueOf(list.get(1).getValue())); 
     topScore3.setText(String.valueOf(list.get(2).getValue())); 
    } 
0

爲了解決可能我recomand最簡單的方法問題,你改變你的數據庫結構是這樣的:

{"top_clicker_db" : { 
    "total_clicks" : 3401, 
    "user" : { 
     "-KkePRVzO_lLLgp7fqX0" : { 
     "fly" : 2000 
     }, 
     "-KkjWk0L2lR8RwUXF2Bd" : { 
     "lg" : 24 
     }, 
     "-KkjjxNw8fj_XG9uUPEg" : { 
     "fjfg" : 304 
     }, 
     "-KkjoakdLIjYlBEM1pkq" : { 
     "Geny" : 100 
     }, 
     "-KklVAOkk2WJaRmH9cKk" : { 
     "fly" : 941 
     } 
    } 
    } 
} 

你需要一個孩子the user name as the keythe score as the value。這種結構的好處是你只需要查詢一次。要達到此目的,請使用以下代碼:

DatabaseReference yourRef = FirebaseDatabase.getInstance().getReference().child("top_clicker_db").child("user").child(userId); 
Query query = yourRef.child(userName).orderByValue().limitToFirst(3); 
ValueEventListener eventListener = new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     Log.d("TAG", dataSnapshot.getKey() + "=" + dataSnapshot.getValue()); 
    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) {} 
}; 
query.addListenerForSingleValueEvent(eventListener); 

希望它有幫助。

+0

謝謝。但我無法改變我的數據庫結構。在我的應用程序中,我獲取用戶對象但我會考慮一下。 –

+0

好的。保持我的發佈。 –

+0

我解決了這個問題。 –

0

你說你不能在@ alex-mamo的回答中的評論中改變你的數據庫結構,但是如何添加一個新節點?

如果可以,將數據非規範化也可能是一個好的解決方案。 https://firebase.google.com/docs/database/web/structure-data

"total_clicks" : 3401, 
"user" : { 
    "-KkePRVzO_lLLgp7fqX0" : { 
    "name" : "fly", 
    "userScore" : 2000 
    }, 
    "-KkjWk0L2lR8RwUXF2Bd" : { 
    "name" : "lg", 
    "userScore" : 24 
    ... 
}, 
"scores" : { 
    "-KkePRVzO_lLLgp7fqX0" : { 
    "fly" : 2000 
    }, 
    "-KkjWk0L2lR8RwUXF2Bd" : { 
    "lg" : 24 
    }, 
    ... 
}