Getting rank of user from firebase database in android - android

I have a real time firebase database that stores a list of users and it's stored in the following format(Json)
{
"users" : {
"-L29HeOZCmYu9UGJLMQR" : {
"name" : "John Doe",
"phoneNumber" : "+555-1566",
"points" : 21,
"rank" : 10,
"userId" : "-L29HeOZCmYu9UGJLMQR"
},
"-L2ASCuStoH7CTaqgBgG" : {
"name" : "Jenna Rose",
"phoneNumber" : "+555-3562",
"points" : 96,
"rank" : 0,
"userId" : "-L2ASCuStoH7CTaqgBgG"
},
....// A lot more users.
}
So my question is, how do I get the rank of the user in terms of the "points" variable? Also, how do I prepare a list of the top 10 or the top 100 etc..?

There is no way to get the rank of a specific user, without loading all users.
But you can get the top N users by using Firebase's query mechanism to sort and filter data. For example:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("users");
Query top10query = ref.orderByChild("points").limitToLast(10);
top10query.addChildEventListener(...
The children will be in ascending order. You'll have to revert them client-side, for example by adding each subsequent child to the top of the list.

Related

Firebase Realtime Database Filter Data in Nested List

I wanted to retrieve filtered data from db according to extra_Cat value like 31
I am able to retrieve full data easily but unable to put filter in it
Note: I have checked almost every solution, If duplicate please reply then tag duplicate
my code is
DBConnection dbConnection=new DBConnection();
postRef=dbConnection.database.getReference("Data");
postRef.child("extra_Cat").orderByKey().equalTo("*31*").limitToLast(500).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long as= dataSnapshot.getChildrenCount();
Log.d("Data", String.valueOf(as));
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
}
});
and JSON is
"32161" : {
"author_name" : "Talented+Desk",
"cat_ID" : "%2A7%2A",
"cat_name" : "%E0%A4%96%E0%A5%87%E0%A4%B2",
"content" : "A4%B5A4%A8%E0%A4%BF%E0%A4%AF%E0%A4%AE+%E0%A4%B9%E0%A5%88%E0%A4%82%7C%E2%80%9D%3C%2Fp%3E%0A",
"extraCat" : [ "*31*", "*14*" ],
"fea_image" : "https%3A%2F%2Fwww.talentedindia.co.in%2Fwp-content%2Fuploads%2F2018%2F03%2Faajeevan-pratibandh-Steve-Smith.jpg",
"post_comment" : "0%A4%BF%E0%A4%AF%E0%A5%8B%E",
"post_date" : "2018-03-26",
"post_id" : "32161",
"post_slug_name" : "kangaroos-protest-against-less-punishment",
"post_status" : "publish",
"post_time" : "10%3A45%3A40",
"post_video" : "",
"slider_image1" : "",
"slider_image2" : "",
"slider_image3" : "",
"slider_image4" : "",
"title" : "%E0%A4%94%B8%E0%A4%9C%E0%A4%BE+%E0%A4%AA%E0%A4%B0+%E0%A4%B5%E0%A4%BF%E0%A4%B0%E0%A5%8B%E0%A4%A7"
},
You cannot create a query based on values that exist within an array. As I see in your database, extraCat is an array which contains 2 values, *31* and *14*.
In order to solve this, you need to change your database structure a little bit. So your extraCat node should look like this:
extraCat
|
--- "*31*": true
|
--- "*14*": true
As you can see, the extraCat node the is now a Map. The corresponding query should look like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Data")
.orderByChild("extra_Cat/*31*")
.equalsTo(true)
.limitToLast(500)
.addValueEventListener(/* ... */)
First you are using wrong reference path. The current you are using is Data/extra_cat. As I see in your Firebase structure it should be Data/32343/extraCat.
You can't use .child("extra_Cat").orderByKey().equalTo("*31*") because the *31* is not of the extra_Cat keys value. The value is in the list.

How to paginate in Firebase Database #AskFirebase

I am creating an application that is some kind of a personal vocabulary. The database is of the following form.
Now I need to implement a pagination, partial retrieval of the words of a user, but preserving the lexicographical order. Keeping words as keys (/user/{uid}/words/{word}) is not suitable, because handling homographs will be impossible in the future (as their key will coincide). I decided to keep additional property word for each user, so that I can call db.getReference().child("users").child(uid).child("words").orderByChild("word").
This will retrieve all words of a user. Now I need to paginate this query, e.g. first download 20 words and then again 20 etc., but preserving lexicographical order.
{
"users" : {
"yXYSqB016JMr1FIc85pvMbvqDDt2" : {
"words" : {
"5v1a1PaDKnTvvOH19kaFTa1iyOx2" : {
"index" : 1,
"word" : "apple"
},
"kXHakBKxk9TrAlWL1vTOCe0akk80" : {
"index" : 2,
"word" : "house"
},
"xSKSqB312JMrsFig15pvMbvqAAt0" : { ... }
}
},
"zCAtMpl9uxSjG9dJarGktTTs20w2" : { ... }
},
"vocabulary" : {
"en" : {
"5v1a1PaDKnTvvOH19kaFTa1iyOx2" : {
"definitions" : {
"a fruit that grows on a tree" : true
},
"word" : "apple"
},
"kXHakBKxk9TrAlWL1vTOCe0akk80" : { ... },
"xSKSqB312JMrsFig15pvMbvqAAt0" : { ... }
}
}
}
You seem to come from a SQL way of thinking, where you paginate by specifying the number of items to get and the number of items to skip. This is index-based pagination.
Firebase on the other uses cursor-based pagination. You tell it the nimber of items to get and at which item to start (or end). You identify this item by the value of the property on which you order, in your case that is the value of word. Since the same value could potentially appear in multiple children, you can also specify the key (the thing starting with 5v1a1...) of the child at which to start/end as a second parameter.
So say that you have a page size of two. You get the first 2 words with:
DatabaseReference allWords = db.getReference().child("users").child(uid).child("words");
Query firstPage = allWords.orderByChild("word").limitToFirst(2);
When you attach a listener to this, you'll get the first two words. You'll need to remember the word and the key of the last word in this first page:
String lastWordOnPreviousPage = "house";
String lastKeyOnPreviousPage = "5v1a1...";
Now if you need the second page of two words, you get them by:
Query secondPage = allWords.orderByChild("word").startAt(lastWordOnPreviousPage, lastKeyOnPreviousPage).limitToFirst(2);

Firebase - Filtering Query Data

I have a group of comments for different blog posts.
The problem now is every comment displays on every blog post.
Im calling the data with
myref= FirebaseDatabase.getInstance().getReference().child("comments");
Which returns all comments.
This is the data JSON
{
"comments" : {
"-KgnRe9d5s471yDWVYBk" : {
"_id" : "56e35e39106a750e008c33b5",
"_blogID" : "56ba5f6a894eeb0e008c86c0",
"commentKey" : "-KgnRe9d5s471yDWVYBk",
"detail" : "test comment",
"user" : "john",
"votes" : 0
}
Id like to filter all comments by "_blogID"
Thanks
You can use a Query like this: Query query = myref.child(commentKey).orderByChild("_blogID");

Realtime database get name and value

i am using firebase real-time database.
there is the user name like - user1 and then some supplies he requested like the supplies name - markers and then the quantity - like 5.
this is my JSON file
{
"Users" : {
"User1" : {
"Markers" : 5,
"Scissors" : 1,
"Staplers" : 4
},
"User2" : {
"Markers" : 2,
"Scissors" : 5,
"Staplers" : 3
}
}
}
i want to get back the supplies whan i ask for in the format of:
markers 5
scissors 1
Staplers 4
the information comes out via a listview but i don't know how to get via the listview both name and quantity, i can get only one of them.
The code i am using to get only the names is:
Set<String> set = new HashSet<String>();
Iterator i = dataSnapshot.getChildren().iterator();
while (i.hasNext()) {
set.add(((DataSnapshot) i.next()).getKey());
}
and the code i am using to get only the quantity is:
// two first lines are the same
while (i.hasNext()) {
set.add(((DataSnapshot) i.next()).getValue().toString());
}
Try something like this instead:
for (DataSnapshot supply : dataSnapshot.getChildren()) {
String key = supply.getKey();
String value = supply.getValue();
}
Also, you could have just saved i.next() to a variable, then you can access the key and value within the same loop without calling additional i.next() (which I presume is what the question is about).
i have changed the script to this one
key = (((DataSnapshot) i.next()).getKey());
value = ((dataSnapshot).child(key).getValue().toString());
set.add(key+" "+value);
it works very good, thanks any way.

How to retrieve Firebase data and bind it to a list view?

I am new to Firebase, and am trying to implement it into my Android app. At this moment, I have a list view where I want to show scheduleTime and scheduleName. Let's call this list view lvTodaySchedule.
Next, this is how my data in Firebase looks like
{
"schedule" : {
"-JvA3muNBCoTISLalZZq" : {
"date" : "24 July 2015",
"schedule description" : "Bring some sandwiches and apples",
"schedule name" : "Picnic",
"selected route" : "Route 1",
"time" : "0:52"
},
"-JvA3muNdSdSasdlZAsS" : {
"date" : "24 July 2015",
"description" : "Run around like mad for 20 minutes",
"schedule name" : "CARDIO",
"selected route" : "Route 1",
"time" : "0:41"
}
}
}
What I want to do is retrieve the date, time and name. So basically in SQL logic, retrieve time and name WHERE date = 24 JULY 2015, and the display it ORDER BY time.
The firebase tutorial teaches me to retrieve a dataSnapshot (which is an Object) of the above data, but I have no idea what to do with it.
I also want to display all these info into the list view, so I was wondering if it's possible to retrieve the data and put them in an array or something.

Categories

Resources