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:
- a property combining the month and popularity, for your first query. For example:
"month_popularity": "201812_125"
(if the popularity is 125). - a property combining the month and rating, for your second query. For example:
"week_rating": "2018w51_4"
. - 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
The Specified Child Already Has a Parent. You Must Call Removeview() on the Child's Parent First
How to Configure Launcher Activity Programmatically in Android
How to Store Image Retrieved from Url in a SQLite Database
Firebase Messaging Nosuchmethoderror.Zzur Exception
Android - Firebase Quickstart Email/Password Auth Demo Doesn't Work
Can't Put Double Sharedpreferences
Connectivity_Action Intent Received Twice When Wifi Connected
Am I Getting the Steps Right for Verifying a User's Android In-App Subscription
View Binding - How to Get a Binding for Included Layouts
Server-Side Verification of Google Play In-App Billing Version 3 Purchase
Read Contents of a Url in Android
How to Create Custom Shape Button with Selector in Android
Could Not Launch Emulator in Android Studio
Sliding Navigation Drawer Not Handling Clicks on Menu Items Android
How to Launch an Activity Without a Ui
How to Implement Multi-Selection and Contextual Actionmode in Actionbarsherlock