Firebase Sort by Points Depending on Date

Firebase sort by points depending on date

If you want to query date ranges, you should store them in a format that allows querying ranges. For dates that would be either a timestamp or a string that is lexicographically sortable.

You currently store dates as a dd.MM.yyyy string, which is not lexicographically sortable. I recommend switching to yyyy-MM-dd, so 2019-01-09. That way if you want to get all posts for January, you can do a range query:

ref.orderByChild("date").startAt("2017-01-01").endAt("2017-01-31")

If you already know that you want monthly leaderboard, I'd recommend changing your database structure to reflect that. So: store the scores by the month that they're in:

2017-01
-K34761761238712
name: "GGGG"
score: 3
-K4875731941298a
name: "AAA"
score: 1

That way you can get the high scores for January in order with:

ref.child("2017-01").orderByChild("score").limitToLast(10)

sorting by date in firebase database

There is no way in which you can sort your items by date if you are storing the date as String "29/11/2018" and not as a timestamp.

To solve this, you should change the type of your date property to number.

And here you can how to add and get back the timestamp.

Firebase, how to sort on key within date range

All of these require that you consider multiple properties. And since the Firebase Realtime Database can only order/filter over a single property, you can't perform these without modifying the data model. For a good primer, read my answer here: Query based on multiple where clauses in Firebase

In this case, you'd need three extra properties for each node:

  1. a property combining the month and popularity, for your first query. For example: "month_popularity": "201812_125" (if the popularity is 125).
  2. a property combining the month and rating, for your second query. For example: "week_rating": "2018w51_4".
  3. a property combining the day and rating, for your third query. For example: "day_rating": "20181225_4".

With these properties, you can then order on the interval you want, and filter the values for the range you want. For example to get the top 50 games for this month:

ref.orderByChild("month_popularity").startAt("201812_").endAt("201812~")

Where the ~ is just a character after _ in ASCII, ensuring that we stop returning results after the ones from this month.

How to sort Firebase data according to Time Created?

Because of orderByChild("name"), whenever a new Data is inserted in the Database is not according to the Time

When you are using:

.orderByChild("name")

It means that the results that are coming from the database will be ordered according to the values that exist in the "name" property, and not according to a "time".

Instead, it inserts the data in the RecyclerView in a Random Order.

As said above, that's definitely not a random order. If you need to get the results according to the "time" of the addition, then you have two options.

If, for example, the "M38dJdquf4jE" is a pushed key that is provided by the "push()" method, you can use Query's orderBykey() method, which:

Creates a query in which child nodes are ordered by their keys.

You'll get the results ordered because the pushed keys contain a time component.

If those keys are not provided by the "push()" method, to have an order according to a time component, then you should add a property of type "timestamp", as explained in my answer from the following post:

  • How to save the current date/time when I add new value to Firebase Realtime Database

Once you have that new property in place, you can use:

.orderByChild("timestamp")

To have the results ordered ascending. If you need however a descending order, then you can use my answer from the following post:

  • How to arrange firebase database data in ascending or descending order?

How to Sort Data in Firebase RealTime Database based on Future Date/Time

Ok so I figured out the answer. I will post what I did in case somebody has the same question in the future.

I created a method that transforms String dates into Long(Milliseconds). (This is what the firebase database uses for time and date.)

   public Long toMilli(String dateIn) throws ParseException {
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date date = (Date) formatter.parse(dateIn);
long output = date.getTime() / 1000L;
String str = Long.toString(output);
long timestamp = Long.parseLong(str) * 1000;
return timestamp;
}

I transform the date by calling the method:

//Store date,time and destination on a new Trip.
datePassed = dateText.getText().toString();
timePassed = timeText.getText().toString();

String dateSelected = dateText.getText().toString() + " " + timeText.getText().toString();
Long timestamp = toMilli(dateSelected);

I created a new construction for Trip and store the new timestamp(Long) there and stored the Trip in the database.

    public Trip(String destination, Long timestamp) {
this.destination = destination;
this.timestamp = timestamp;
}

To read the data from the firebase:

    //Get uId of the user
final String uId = currentFirebaseUser.getUid();

dbRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

for (DataSnapshot child : dataSnapshot.child(uId).child("trips").getChildren()) {
String destination = child.child("destination").getValue().toString();
Long timestamp = child.child("timestamp").getValue(Long.class);

The next step is to transform Long to String, I created a new method for that.

    public String convertTime(long time){
Date date = new Date(time);
Format format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
return format.format(date);
}

And finally call the method:

String time=convertTime(timeLong);

Before reading the data I created a new ArrayList
I then create a new object - Trip in my case and passed in the values.
Everytime I was reading a child trip - with the for loop I was adding it to the list.

At the end I sorted the list before displaying it to the user. You have to override CompareTo in order for this to work.

How to sort an object from firebase?

Your dates are stored as strings in a format that is unfortunately not chronologically sortable. If you want to sort on dates, I recommend storing them in ISO-8601 format, such as "2021-10-15" so that their lexicographical order matches their chronological order.

Once you have that format, you can retrieve the nodes from the database in the correct order with:

DatabaseReference reminders = dbf.child("Reminders");
Query remindersByDate = reminders.orderByChild("date");
remindersByDate.addValueEventListener(...

Also see:

  • Firebase sort by points depending on date
  • Firebase endAt() not working with date string?
  • Querying by range in firebase

Firebase Order By a Date Value from Today Doesn't Work

Most likely the problem is caused by the fact that you do snapshot.val() on the query result. When you request ordered data from the Firebase Database, you get back three things: the keys, the values, and the order of the items.

When you call val() on a snapshot you get back a JSON representation of the value, which has room for only the keys and the values. And since the order of properties in a JSON object is undefined, the order of your results is undefined (though most browsers show them ordered by key).

To solve this problem, use Snapshot.forEach() to iterate over the result in the snapshot:

return ref.on('value', (snapshot) => {
var events = [];
snapshot.forEach((child) => {
events.push(child.val());
});
console.log(events);
});


Related Topics



Leave a reply



Submit