[JAVA] Create a clear time ranking in Firebase's Realtime Database (Android app)

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. qiita.png

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.

Rule creation

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.

Data registration

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);

Data acquisition

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

Create a clear time ranking in Firebase's Realtime Database (Android app)
Create a database in a production environment
Create a new app in Rails
I tried to create a simple map app in Android Studio
Create a TODO app in Java 7 Create Header
From setting up Firebase's Realtime Database to simple data entry (Android app)
[Android / Java] Operate a local database in Room
I tried using a database connection in Android development
[Programming complete] ยง5 Create a review management app in Ruby
Create a Servlet program in Eclipse
Try to create a server-client app
I made a matching app (Android app)
[Kotlin / Android] Create a custom view
[Android] I made a pedometer app.
To create a Zip file while grouping database search results in Java