Displaying latest into custom Info window by timestamp from Firebase [duplicate] - android

I am developing an Android chat application in which I need to order the conversation details by the date. My firebase data structure is mentioned below.
Now I want to retrieve and show the data on the latest date on my RecyclerView from Firebase Realtime Database based on timestamp.
I have tried the following approaches.
final DatabaseReference nm =
FirebaseDatabase.getInstance().getReference("Transaction");
Query query = nm.orderByChild("Date").limitToFirst(5);
;
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
listData.clear();
if (dataSnapshot.exists()) {
for (DataSnapshot npsnapshot : dataSnapshot.getChildren()) {
Transaction ld = npsnapshot.getValue(Transaction.class);
listData.add(ld);
}
Tadapter = new TransactionAdapter(listData);
rv.setAdapter(Tadapter);
Log.d(TAG, "Total Count" + Tadapter.getItemCount());
}
}
}

I am developing an android chat application in which I need to order the conversation details by the date.
As I see in your screenshot, your Date property is of type String. This means that you cannot call:
.orderByChild("Date")
And expect to behave as it was a Timestamp. When you order String elements, the order that you get is always lexicographically. This means that Strings doesn't consider any sort of numeric values when sorting, especially when it comes to the dates, even if the dates contain numbers, as your first element does:
Date: "30/7/2021"
So using String values when querying your database it's not an option. However, I see you already have a Timestamp property. Maybe on that property, it was supposed to do the ordering. If that was not the case, I suggest you change the type of the Date property from String to 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
Now I want to retrieve and show the data on the latest date on my RecyclerView
This means that most likely you need to reverse the order, meaning that all your transactions have to be displayed in your RecyclerView descending. In this case, there are a few options that you have, either on the server or on the client.
Assuming that you have changed the type of your Date property from String to Timestamp, then you can simply consider storing an inverted Timestamp value like this:
Firebase-root
|
--- transactions
|
--- 1
|
--- Date: 1627714194
|
--- invertedDate: -1627714194
See, the invertedDate property holds a negative value. Since by default, the elements are ordered ascending, to be able to order the transaction desecendiong, you should simply use:
Query query = nm.orderByChild("invertedDate").limitToFirst(5);
On the other hand, there are some workarounds that can be made to achieve the same thing on the client, as explained in my answer from the following post:
How to arrange firebase database data in ascending or descending order?

Query query = nm.orderByChild("Date").limitToFirst(5);
Firebase realtime database sorts in ascending order that means those 5 nodes that you'll receive will be the oldest.
I want to retrieve and show the data in latest date
Try using limitToLast instead which will return the last 5 documents after ordering the nodes by Date field i.e. the 5 latest nodes.
Query query = nm.orderByChild("Date").limitToLast(5);
You can read more about that at sorting and filtering data.

Related

Firebase orderBy timestamp not actually ordering

I have a query that orders by my timestamp value in my server, the currently timestamp is set by my pojo as a date
data class Timestamp(#ServerTimestamp val timestamp:Date? = null)
This timestamp is place in firestore as
But when I do my fetch code
val snapshot = FirebaseFirestore
.getInstance()
.collection("orders")
.whereEqualTo("uid",currentUser.uid)
.whereLessThan("status",Status.DELIVERED.statusNumber)
.orderBy("status",Query.Direction.DESCENDING)
.orderBy("timestamp",Query.Direction.ASCENDING)
I want to see first on the list the latest orders I did, but instead , is mixing my old orders with the new ones, my goal here is to bring up first the newest orders I placed inside orders collection, but instead it does not order it when new orders are created
If you want newest documents first, you should do a DESCENDING order on timestamp. If you want the list to be primarily sorted by timestamp, and secondarily sorted by status, the timestamp orderBy it should come before the orderBy on status (right now, you are sorting primarily on status and secondarily on timestamp).
.orderBy("timestamp",Query.Direction.DESCENDING)
.orderBy("status",Query.Direction.DESCENDING)

How to order firebase data from the latest

Firebase by default orders data from the earliest and I need it to be ordered from the latest.
I am using timestamp to do so and doesn't seem to be working.
private void filldata() {
mDatabase.child("Data").orderByChild("timestamp").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String s) {
System.out.println("snapshot:" + snapshot.toString());
}
}
You no need to use orderByChild() here in your case because firebase itself generate unique key which is based on a timestamp, so you can simply use orderByKey() in your query and you will get your data in latest order.
The unique key is based on a timestamp, so list items will
automatically be ordered chronologically. Because Firebase generates a
unique key for each blog post, no write conflicts will occur if
multiple users add a post at the same time.
You can find more here
I'll suggest to use
mDatabase.child("Data").orderByKey().limitToLast(no_of_items_you_want)
This will give you list of latest data
Also to get value from snapshot use
snapshot.getValue(String.class);
Since orderByChild() only sort data in ascending order, you should store an extra data item in your child node whith the value timestamp*(-1) and then sort (order) on this data item.
Your code is correct. The commonly suggested way to order will be by using a negative timestamp.
However I have noticed previously that firebase does order your results by timestamp, as you currently wish for it to do. When the device receives the results it reorders the results by arrival (suspicion).
To test this, try limit your results by using the .limitToLast(n) function, you will realize that while firebase will return the last 10 (in order of timestamp) results to you, these results will not be ordered by timestamp.
Therefore, the best solution will be to store the firebase results in a list and reorder the list using a sorting tool like a comparator

How to store ServerValue.TIMESTAMP as a string in Firebase database

I've an a firebase recyclerview and I want to query that datas in a OrderByChild for example TOPWEEK or TOPDAYS in order to that I planning to combin ServerValue.TIMESTAMP with star counts such as
"Combin" : "1522741072_5"
first value is timestamp second value is star counts. but if I made this every time new one goes top, star counts is ignored (because of timestamp is in mili sec). I thinking that I should trim some value from timestamp. like this:
String.valueOf(ServerValue.TIMESTAMP).substring(0,4)
but it is not possible because I cant store timestamp as a string in firebase database. this is my model class
#Exclude
public Map<String, Object> haritala() {
HashMap<String, Object> result = new HashMap<>();
result.put("yazar", yazar);
result.put("baslik", baslik);
result.put("uid",uid);
result.put("favsays", favsays);
result.put("fav", favori);
result.put("mesajsays", mesajsays);
result.put("mesaj", mesaj);
result.put("Combin", ServerValue.TIMESTAMP);
return result;
}
Are there any solution
According to your last comment, I understood that the star counts does not contains a fixed value, it can be incremented by users. In this case, your solution will not work. There is another solution to have two separate properties but unfortunately, Firebase Realtime database does not support queries on multiple properties, supports only queries on a single child property. Also you should not consider augmenting your data structure to allow a reverse lookup because in that case you'll have to many nodes.
If I were you, every time I should add a new item to the database, I'll use the push() method, which will generate as the key of the item, a random key which is based on time. So by default, all your items will be sorted by creation time. In this case, you'll only need to use a query that will look like this:
Query query = rootRef.child("results").orderByChild("reuslt");
Don't forget to set the value of result property as an Integer or as a Long, not as a String because in case of string the items are ordered lexicographically.
You can consider take a look at Cloud Firestore, in which chained queries are permitted.

Search child nodes in firebase database using android

Hello guys here is my firebase database:
I want to get list of all medicines with particular symptoms.
Here is my code i.e what i have done
public void initializeMedicineListener(String node,String type,String value){
mDatabase=mFirebaseInstance.getReference();
Query query = mDatabase.child("Medicine").child("symptoms").orderByChild("name").equalTo("Neck pain");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
medicineList=new ArrayList<Medicine>();
if (dataSnapshot.exists()) {
for (DataSnapshot medicine : dataSnapshot.getChildren()) {
Medicine data = medicine.getValue(Medicine.class);
medicineList .add(data);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
But i am getting null results.
Please guide me guys.Am i doing something wrong??
When you run a query at a location, Firebase check each child node at that location for the property that you order on and the range/condition you filter on.
mDatabase.child("Medicine").child("symptoms").orderByChild("name").equalTo("Neck pain");
So this checks the children of /Medicine/symptoms for their name property and only returns them if they have a value equal to Neck pain.
There are two problems with this:
Your JSON doesn't have a /Medicine/symptoms. Instead you have a Medicine, where each child node has a symptoms node.
Even if it did, your symptoms child doesn't have a value Neck pain. Instead you have an array, where each value may be Neck pain.
The closest you can now get to the query you want is:
mDatabase.child("Medicine").orderByChild("symptoms/0/name").equalTo("Neck pain");
This query returns medicines for which the first symptom name is equal to Neck pain. Firebase cannot perform a query across all array members to see if it contains a specific value in any position.
As usual with NoSQL databases: if you can't perform the use-case you want with your current data structure, you can typically change/expand your data structure to allow the use-case. And usually this is done by very directly mapping what you want to show on your screen to the structure in the database.
Your current data structures allows you to efficiently look up the symptoms (and other data) for a given medicine. That's great. It does however not allow you to efficiently look up the medicines for a given symptom. To allow that you can for example add a structure that maps each specific symptom back to its medicines:
symptoms
"Neck pain"
-L6hb2...bRb0: true
-L6rW...Fuxkf: true
With this additional structure (known as an inverted index or reverse index) you can now look up the medicines for Neck pain by simple loading /symptoms/Neck pain.
For more on this approach to categorization, see my answer here: Firebase query if child of child contains a value
You can't work with firebase database as relational databases .. instead of what you looking for .. you can create new node like this
medicineSymp
---neckpain
-------medicine1ID
-------medicine1ID
-------medicine1ID
this way you could get all medicines much faster and easier

Retriving Data From Firebase In DataSnapshot ( Not In Sequence )

I saved the data into Fire base but when I retrieve it. The data is not in the sequence.
Here Data Is Saved In Accurate Sequence:
But when I retrieve data lost its sequence:
Here is my code for retrieving Data
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users").child(Autho_User.getUid()).child("Data");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(" Value = "+dataSnapshot.toString());
}
(Printed it just to check values) Data is not in the sequence even I get it through
dataSnapshot.getvalue();
Hope so you got my question. I need the data in sequence
Firebase stores JSON data. By definition the children under a node in JSON are unordered. It is only when the data is displayed or retrieved that it gets an order. So the first screenshot that you show is just the order in which the Firebase Database console display it.
If you want to get the data in a specific order in your application, you need to do two things:
Execute a query that returns the data in that order.
Ensure that your code maintains that order.
The code you shared does neither 1 nor 2, so the order in which the data is printed is anybody's guess. Usually it will be in lexicographical order of the keys, but it is undefined.
To learn how to order/filter data, read the Firebase documentation on ordering and filtering. To learn how to maintain the order of items when you use a ValueEventListener, read the Firebase documentation on listening for value events. When you combine these two, you get:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users").child(Autho_User.getUid()).child("Data");
Query dataOrderedByKey = ref.orderByKey();
dataOrderedByKey.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
System.out.println("Key = "+childSnapshot.getKey()+" Value = "+childSnapshot.toString());
}
}
...
This is an incredibly common mistake/question, so here are some previous questions for reference:
How to Convert Firebase data to Java Object...?
Ordering of data with Firebase Android
Firebase returning keys of child node in different orders on different devices/Android versions
How to sort by children key value in firebase?
Firebase .getvalue not in the same order as database
Order by date in negative timestamp is not working in Firebase

Categories

Resources