Continuing from the previous session. https://qiita.com/KIRIN3qiita/items/4573d26187b8c9e53fc6
This time, we will create a ranking of game clear time as a practical version of Realtime Database.
This is a clear time ranking image of a change payment game I created a long time ago.
Even if you make your own mobile app, it will take shape a little if you have a clear time ranking. (Although the number of installations is about 100 ...) Supreme payment (https://play.google.com/store/apps/details?id=jp.kirin3.changegame&hl=ja) If you apply this, you can also make score rankings.
Use $ Variables to create a rule to store per-user data.
About $ Variables --------------------------- You can capture part of a read or write path by declaring a capture variable with the $ prefix. This acts as a wildcard and saves the value of that key for use inside the rule declaration. ---------------------------
I created a rule to save the name, clear time, clear date and time, and user ID for each user.
rule
{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
"info": {
".read": true,
".write": true,
"$user_id": {
"name": {
".validate": "newData.isString() &&
newData.val().length < 9"
},
"time": {
".validate": "newData.isNumber()"
},
"date": {
".validate": "newData.isString()"
},
"user_id": {
".validate": "newData.isString()"
}
}
}
}
}
It is unpleasant to have "user_id" in the "$ user_id" item, but it is convenient if it is an image that extracts data in the same hierarchy.
First, create a class to be used for data storage and acquisition.
User
public static class User {
public int rankingNo;
public String name;
public Double time;
public String date;
public String userId;
//Empty constructor declaration required
public User() {
}
public User(String _name, Double _time,String _date, String _userId) {
name = _name;
time = _time;
date = _date;
userId = _userId;
}
public void setRankingNo( int _rankingNo ){
rankingNo = _rankingNo;
}
public Integer getRankingNo(){
return rankingNo;
}
public String getName(){
return name;
}
public Double getTime(){
return time;
}
public String getDate(){
return date;
}
public String getUserId(){
return userId;
}
}
Data registration
//For the time being, UserId is created with UUID. (After that, it is necessary to save it in the reference so that it does not change every time)
String sUserId = UUID.randomUUID().toString();
User user = new User( "UMEHARA",5.3,"2019-10-21 09:00:27" ,sUserId);
//Get an instance
FirebaseDatabase database = FirebaseDatabase.getInstance();
//Get reference by specifying file path
DatabaseReference ref = database.getReference("info");
//Register data
ref.child(sUserId).setValue(user);
Register the terminal data only once before acquisition. (I will explain why it is necessary later)
Termination data registration
public void SaveTerminal(){
String userId = TARMINAL;
String userName = "Terminal";
Double time = 99999.9;
String date = "1999-01-01 00:00:00";
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("info");
User user = new User( userName,time,date,userId );
ref.child(userId).setValue(user);
}
Data acquisition
//User data array
public static ArrayList<User> sUsers;
//Maximum number of rankings
final int OUTPUT_RANKING_NUM = 100;
FirebaseDatabase database = FirebaseDatabase.getInstance();
//Get reference by specifying file path
final DatabaseReference refUser = database.getReference("info");
//Sort by clear time, set maximum number of acquisitions
refUser.orderByChild("time").limitToFirst(OUTPUT_RANKING_NUM + 1).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
User user = dataSnapshot.getValue(User.class);
//Ranking rank is also saved in the object
sRankNo++;
user.setRankingNo(sRankNo);
//When you receive the termination data, pass it to the adapter and display it in the list view
if( dataSnapshot.getKey().equals(TARMINAL) || sRankNo == OUTPUT_RANKING_NUM + 1 ){
UserAdapter adapter = new UserAdapter(getApplicationContext(), 0, sUsers);
sListView.setAdapter(adapter);
}
//Save to array
else {
sUsers.add(user);
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Put the acquired data in an array, pass it to the adapter, and display it in ListView. The data is sorted by clear time and is set to retrieve up to 100 items. Since it is not possible to determine the completion of data acquisition, the end data (the data to be acquired last) is registered to determine the end of the data. There may be a better way to write it, such as "user_id" in the "$ user_id" item in the rule statement, but I hope you can refer to it as it still works. Realtime Database has a lot of habits and is difficult to use.
Recommended Posts