Returning zero nodes in realtime startAt query - android

Im trying to make pagination with Realtime db. I am making query first time with limit 15 and second time based on last item uid i am making second query where suppose to startAt() with that uid. After first query I am receiving as it suppose to 15 items. Next time it suppose to send me back 9 items. But it sends me zero
The code of response
DatabaseReference mReference = realtimeReference.child("OnlineUsers/" + neededGender);
Query query;
if (uid.equals("")){
query = mReference.orderByChild("rating").limitToLast(TOTAL_ITEMS_TO_LOAD);
}else {
//Pagination query with last uid to start
query = mReference.orderByChild("rating").startAt(uid).limitToLast(TOTAL_ITEMS_TO_LOAD);
}
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final List<OnlineUser> userList = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
OnlineUser user = postSnapshot.getValue(OnlineUser.class);
userList.add(new OnlineUser(user.getUid(), user.getName(), user.getImage(), user.getGender(), user.getCountry(), user.getRating()));
}
EventBus.getDefault().post(new ListEvent(userList));
}
Database structure

When paginating, you always need to pass the value of the property that you order on. In addition, if there are multiple nodes with the same value for that property, you should pass the key of of the first item to return.
So in your case that'd be:
mReference.orderByChild("rating").startAt(rating, key).limitToLast(TOTAL_ITEMS_TO_LOAD);
This assumes that you have the rating of the node in rating and its key in key.

Related

Retrieve data from multiple push ids under a single child in firebase realtime database

I am new to android studio and programming and am currently trying to make my first app. In firebase RTDB, I have multiple push ids under a single child that keep on increasing in number as the user presses certain buttons, and they all store only an integer. I want to retrieve the data from all those push ids(or keys, I don't really know what they are actually called) under the child and then sum the integers up and display the result in a textView and do it every time a new field is added. How can I do that? So far I only know how to normally send and receive data to childs sub-childs like this but i have never ever used push ids or keys before:
String recieve = datasnapshot.child("Child").child("subchild").getText().toString();
String send = "send";
databaseReferenc.child("Child").child("sunchile").setValue(send);
The data tree in firebase is as follows:
Assuming that Australia is a direct child of your Firebase Realtime Database root, to sum all those values, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference australiaRef = rootRef.child("Australia");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int total = 0;
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String value = Integer.parseInt(ds.getValue(String.class));
total += value;
}
Log.d("TAG", "total: " + total);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
australiaRef.addListenerForSingleValueEvent(valueEventListener);
One more thing. Because you are storing numbers, it best to store them as long values and not as String values.

How can I orderByChild on Android Firebase chat based application?

I'm trying to build a user to user chat application, but I'm not able to order the chat list by last message sent.
My Firebase (real time) structure is like this:
I'm trying to retrieve the data like this, but i'm not able to order by "timestamp" in the inner message.
final String uID = firebaseAuth.getCurrentUser().getUid();
Query ref = FirebaseDatabase.getInstance().getReference("Messages");
ref.orderByChild("timestamp").startAt(uID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Did anyone knows how can I order the list of users by the timestamp of the last message?
You need to change the query to the following:
final String uID = firebaseAuth.getCurrentUser().getUid();
Query ref = FirebaseDatabase.getInstance().getReference("Messages");
ref.child(uID_uID).orderByChild("timestamp").addValueEventListener(new ValueEventListener() {
You need access to the direct node under the node Messages, the node with underscore. Then you can add orderByChild("timestamp").equalTo("157644739279")

How to descending order in Firebase realtime with pagination?

Im making query and trying to make an order by rating field. This is paginated list so im making partially queries.
But my query is not sorted.
private void callRealOnlineUsersList(int page, String neededGender) {
DatabaseReference mReference = realtimeReference.child("OnlineUsers/" + neededGender);
Query query = mReference.limitToLast(page * TOTAL_ITEMS_TO_LOAD);
query.orderByChild("rating");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final List<OnlineUser> userList = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
OnlineUser user = postSnapshot.getValue(OnlineUser.class);
userList.add(new OnlineUser(user.getUid(), user.getName(), user.getImage(), user.getGender(), user.getCountry(), user.getRating()));
}
EventBus.getDefault().post(new ListEvent(userList));
}
Logs are
D/testList: rating 2
D/testList: rating 1
D/testList: rating 25
D/testList: rating 3
D/testList: rating 1
D/testList: rating 4
D/testList: rating 1
D/testList: rating 10
D/testList: rating 2
D/testList: rating 1
D/testList: rating 25
Datasnapshot
So, you've combined 3 questions into 1:
Why isn't my code sorting at all?
Why can't I sort in descending order?
Given a query that works, how should I do pagination with Firebase RTDB on Android?
Good news, the later 2 of these have good existing answers on StackOverflow!
First, the way you're using Query here:
Query query = mReference.limitToLast(page * TOTAL_ITEMS_TO_LOAD);
query.orderByChild("rating");
isn't correct (and this is why you aren't getting sorted results at all).
Instead try this:
Query query = mReference
.limitToLast(page * TOTAL_ITEMS_TO_LOAD)
.orderByChild("rating");
If you just call orderByChild, it returns a query that does that, but in your code you are ignoring the result.
To help make it clearer what is happening, you could also do this and it would work (but your current code doesn't save the result of the orderByChild call:
Query query = mReference.limitToLast(page * TOTAL_ITEMS_TO_LOAD);
query = query.orderByChild("rating");
Second, you can't sort by descending order in Firebase RTDB, so you should look at that question for possible solutions.
Finally, your current code will always be returning larger and larger numbers of results as page increases -- you don't always get just TOTAL_ITEMS_TO_LOAD results. A more complete SO question about pagination is here.

OrderByChild() is not sorting my firebase data

I am new in firebase, I want to sort data, by timestamp and my database is below, here key is timestamp
My code for retrieving data is below
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("MainDoor");
Query dataOrderedByKey = myRef.orderByChild("{pushId}/key");
dataOrderedByKey.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, MyListData> value = ((HashMap<String, MyListData>) dataSnapshot.getValue());
Here i am getting value is not by order of key
I am getting data like below which is not in sort order
Data in a Map is by definition not sorted. So when you call dataSnapshot.getValue(), all information about the order of the items in the DataSnapshot is list.
To maintain the order, use a data structure that supports that, such as a list, and extract the individual items in the correct order by looping over DataSnapshot.getChildren().
So something like:
dataOrderedByKey.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
System.out.println(snapshot.getKey());
MyListData value = snapshot.getValue()
}
}
...
Also you can get data from firebase in sorted order . Refer my answer at Sort Firebase data in ascending/Descending Order
You want to sort by date, right? Try it
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("MainDoor");
myRef.orderByChild('date').addChildEventListener(new ChildEventListener() {
// implement the ChildEventListener methods as documented above
});
Because of the way JavaScript objects work, the ordering of data in the JavaScript object returned by val() is not guaranteed to match the ordering on the server nor the ordering of child_added events. That is where forEach() comes in handy. It guarantees the children of a DataSnapshot will be iterated in their query order.
// Assume we have the following data in the Database:
{
"users": {
"ada": {
"first": "Ada",
"last": "Lovelace"
},
"alan": {
"first": "Alan",
"last": "Turing"
}
}
}
// Loop through users in order with the forEach() method. The callback
// provided to forEach() will be called synchronously with a DataSnapshot
// for each child:
var query = firebase.database().ref("users").orderByKey();
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
// key will be "ada" the first time and "alan" the second time
var key = childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
});
});

How to search anywhere in string in Firebase Database - Android

I have implemented firebase realtime database in my android app, everything is fine. I am trying to add a a search function and I am able to search the database with only starting word match.
Below is my database snapshot:
I am querying for movieName. Right now I am able to search if the query string is Pets/Pe/pet. But when I search for Animals, I get zero results. So, basically what I am looking for is searching the database with query text anywhere in the string. ie., I should be able to search Animals/and/pets and should get the results which contain the search query.
Below is my code so far.
mDatabaseReference.child("recent").getRef().orderByChild("movieName").startAt(query)
.endAt(query + "\uf8ff")
To seach for a string within a String please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference animalsRef = rootRef.child("Animals");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Boolean found;
String search = "Animals";
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String movieName = ds.child("movieName").getValue(String.class);
found = movieName.contains(search);
Log.d("TAG", movieName + " / " + found);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
animalsRef.addListenerForSingleValueEvent(eventListener);
As you see, we query the database for all the movie names and then search for the desired word within the movieName.
First of all check the exact child and initialize the Firebase as like. Have a look at this answer,
https://stackoverflow.com/a/34537728/5746625

Categories

Resources