Firebase query return wrong value - android

when I use OrderByChild or key with startAt or equalTo it returns wrong value
This is with equalTo
String diy = intent.getStringExtra(PARCELABLE_KEY);
Query qr = dr.child(AddDIYFragment.DIY_CHILD).orderByChild("title").equalTo(diy);
This is with startAt
Query searchQueryNum2 = reference.child(AddDIYFragment.DIY_CHILD).orderByChild("title").startAt(text);
searchQueryNum2.addListenerForSingleValueEvent(this);
I try orderByKey but it also doesnt work
EDIT JSON TREE EXAMPLE(EDited but I cand add more)
{
"gg0" : {
"category" : "lifestyle",
"eq" : "SMTH",
"title" : "gg"
},
"hdhshs5" : {
"category" : "Sports",
"eq" : "hshsj",
"title" : "hdhshs"
},
"hdhshsjsjs6" : {
"category" : "Sports",
"eq" : "eooe",
"title" : "hdhshsjsjs"
},
"java1" : {
"category" : "Sports",
"eq" : "hshjs",
"title" : "java"
},
"jshsjs7" : {
"category" : "Sports",
"eq" : "hdhshsjjs",
"title" : "jshsjs"
},
"jsjsjsjs9" : {
"category" : "Sports",
"eq" : "hshshwhw",
"title" : "jsjsjsjs"
},
"papajs8" : {
"category" : "Sports",
"eq" : "hdhshhajasjjs",
"title" : "papajs"
},
"sjs4" : {
"category" : "Sports",
"eq" : "hdhs",
"title" : "sjs"
}
}
EDIT onDataChange:-
this is a simple startAt
Query searchQueryNum2 = reference.child(AddDIYFragment.DIY_CHILD).orderByChild("title").startAt("gg");
Log.d(TAG, "query is made");
searchQueryNum2.addListenerForSingleValueEvent(this);
And onDataChange
private ArrayList<Prod> list = new ArrayList<>();
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot temp : dataSnapshot.getChildren()) {
list.add(temp.getValue(Prod.class));
Log.d(TAG, "list added something " + list.get(list.size() - 1));
}
}
EDIT
I set the child to be orderd by startat "gg" and as you see in the top we have gg but it return also (hdhshs,java,jsjsjsjs,papajs ,sjs, etc)

Your query is:
...orderByChild("title").startAt("gg")
This is executed by Firebase in the following way:
Order all children of the reference by their title.
Find the child whose title start with gg, or the first one after that if no child starts with gg.
Start returning results from there, until we run out of results.
I think you're looking for a startsWith(...) operator, which Firebase doesn't natively have, but can easily be created by combining startAt() and endAt().
...orderByChild("title").startAt("gg").endAt("gg\uf8ff")
With this, you're adding an extra step to the recipe above:
Stop returning results once we reach a title that is greater than gg\uf8ff.

Related

OrderByChild() results is depending on case of the words

Current firebase database is:
{
"user_type" : {
"number1" : {
"name" : "Puneet",
},
"number2" : {
"name" : "AMAN SINGH",
},
"number3" : {
"name" : "harsha",
},
"number4" : {
"name" : "abhishek",
},
"number5" : {
"name" : "Satya",
},
}
}
I want to sort the list by name in ascending order. So for this code is :
myRef.child("user_type").orderByChild("name");
But it is returning the result as:
{
"admin" : {
"number2" : {
"name" : "AMAN SINGH",
},
"number1" : {
"name" : "Puneet",
},
"number5" : {
"name" : "Satya",
},
"number4" : {
"name" : "abhishek",
},
"number3" : {
"name" : "harsha",
}
}
}
But I am expecting the following order:
{
"admin" : {
"number2" : {
"name" : "AMAN SINGH",
},
"number4" : {
"name" : "abhishek",
},
"number3" : {
"name" : "harsha",
}
"number1" : {
"name" : "Puneet",
},
"number5" : {
"name" : "Satya",
}
}
}
So instead of the current order, it is sorting first capital case letter words and then it is sorting small letter words and merging the list.
The order you're seeing is exactly what I would expect. This is because of the way strings naturally sort. UTF-8 strings with ascii data sort according to the ascii byte value of each character. As you can see from this table, all capital letters sort before all lowercase values. This explains the sort order you're seeing.
If you want the sort order to be alphabetical without regard to case, you will need to store a version of the name string with case normalized. It's common to store strings to sort like this in all lowercase. For example, instead of "AMAN SINGH", you would store "aman singh" in a special child used only for sorting.

Android - Save list of object property with specific key on Firebase

Let's consider a "UserBean" with a property "emails" that is an ArrayList<EmailBean>.
When saved in Firebase it's like :
"users" : {
"$userID" : {
"emails" : [
"0" : {
"type" : "first",
"address" : "google#google.com",
"private" : true
},
"1" : {
"type" : "second",
"address" : "firebase#firebase.com",
"private" : false"
}
],
"name" : "Mitch"
}
}
So is it possible to achieve something like this :
"users" : {
"$userID" : {
"emails" : [
"first" : {
"address" : "google#google.com",
"private" : true
},
"second" : {
"address" : "firebase#firebase.com",
"private" : false
}
],
"name" : "Mitch"
}
}
I would prefer to not having to save each address one at a time.
Maybe there's an annotation to tells Firebase to use this property as a key ?
Regards.
I recomend you using the code below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference emailsRef = rootRef.child("users").child(userId).child("emails");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String type = ds.child("type").getValue(String.class);
ds.child("type").getRef().getParent().setValue(type);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
emailsRef.addListenerForSingleValueEvent(eventListener);
What have i tried with this code? So in order to achieve what you want, first of all we got the value of your type key. Then we get a step up in the tree and set the partent with the value of your type key for each particular node.
Having the value of type in stead of 0, 1 and so on, to get the work done, just remove the type key, from each node using removeValue() method directly on the reference.

Android Firebase getChildrenCount() not counting

I am trying to count the amount of data that has been entered into a specific child into a firebase database.
public void onDataChange(DataSnapshot dataSnapshot) {
if (!registerVote) {
String user = dbAuth.getCurrentUser().getEmail().toString();
myFB.child(uniquePostID).child(dbAuth.getCurrentUser().getUid()).setValue(user);
final Animation likeRotate = AnimationUtils.loadAnimation(getActivity(), R.anim.rotatelike);
final Animation likeZoom = AnimationUtils.loadAnimation(getActivity(), R.anim.zoomlike);
AnimationSet multiLike = new AnimationSet(false);
multiLike.addAnimation(likeRotate);
multiLike.addAnimation(likeZoom);
viewHolder.postVoteBtn.startAnimation(multiLike);
long numOfLikes = dataSnapshot.child(uniquePostID).child(dbAuth.getCurrentUser().getUid()).getChildrenCount();
viewHolder.display.setText(Long.toString(numOfLikes));
Log.d("LONG", Long.toString(numOfLikes));
registerVote = false;
}
I use the data snapshot to add to the database at child
myFB.child(uniquePostID).child(dbAuth.getCurrentUser().getUid()).setValue(user);
but then when I use
long numOfLikes = dataSnapshot.child(uniquePostID).child(dbAuth.getCurrentUser().getUid()).getChildrenCount();
viewHolder.display.setText(Long.toString(numOfLikes));
It always shows as 0 and does not register anything. Each time a different account likes a post, a name is added to the child that matches the post ID. I want to use the getChildrenCount() to count every name that has like a certain post. I have also noticed that getChildrenCount() will perform the count on preloaded data only, my need is to have the data be retrieved in real time.
{
"Blog" : {
"-KgM1HzLwU1RMx13Z41J" : {
"desc" : "Feeling good",
"title" : "Smashed the gym"
},
"-KgM1NlrcBTYUhUYWYBR" : {
"desc" : "Really didn't feel like leaving the house today, so I played call of duty all day.",
"title" : "Stayed inside"
},
"-KgM1PfgkzSeBxUWi_3t" : {
"desc" : "Nothing helps clear your mind like time with friends",
"title" : "Spending time with friends"
},
"-KgM1Wg54bERKNUyKnE2" : {
"desc" : "But don't be afraid to dream big",
"title" : "Everyone starts small"
},
"-KgM1Zojv7q5FhRi_a3u" : {
"desc" : "Finally managed to break my personal best I'd had for months!",
"title" : "New gym PB"
},
"-KgOmll6K6o_sv1JEUcn" : {
"desc" : "A years worth of work comes to an end today, pretty nervous!",
"title" : "Big presentation today"
},
"-KgP1bC4BlAe88XyN_VV" : {
"desc" : "time to present",
"title" : "let's go"
},
"-KgPE7DI2j7R1QLiL3Bb" : {
"Likers" : {
"stg15QKZFhNmTCYrgL5PtQ4wxJf2" : "Joe Bloggs"
},
"desc" : "You've got this",
"title" : "Stay positive"
},
"-KgPG7siKLWKzij1Lu3d" : {
"desc" : "John is looking at this right now",
"title" : "Honours presentation"
},
"-Kne46iBe6ooNFKTv_8w" : {
"desc" : "bugs?",
"email" : "Joe Bloggs",
"title" : "new"
}
},
"Engagement" : {
"-KgP1bC4BlAe88XyN_VV" : {
"Likers" : {
"JXxWjn9nvQcNsvaf3CO7HqUNKKi2" : "Bob Smith",
"stg15QKZFhNmTCYrgL5PtQ4wxJf2" : "Joe Bloggs"
},
"stg15QKZFhNmTCYrgL5PtQ4wxJf2" : "Bob Smith"
}
}
}
Please use this code:
long numOfLikes = dataSnapshot
.child("Engagement")
.child(uniquePostID)
.child("Likers")
.getChildrenCount();
Hope it helps.
I have a feeling you're missing the Likers level from your JSON in your code:
long numOfLikes = dataSnapshot
.child(uniquePostID)
.child("Likers")
.child(dbAuth.getCurrentUser().getUid())
.getChildrenCount();

Firebase whitelist and recyclerView

{
"Events" : {
"events" : {
"-KT5UMQAhDHs1bB8bKLc" : {
"activity" : "biking",
"address" : "54°05'45.8\"N 28°19'02.9\"E, просп. Мира 9, Жодино, Беларусь",
"category" : "sport",
"creatorID" : "m11EvlP19OSbEz8XYl2MsNCwGXX2",
"date" : 1475431200689,
"forFriends" : true,
"info" : "вттчтвт",
"name" : "ьаьатвтвтт",
"uid" : "-KT5UMQAhDHs1bB8bKLc"
},
"-KUSsl7RaL-dVoDCoSYT" : {
"activity" : "picnic",
"address" : "Узденский район, Узденский район, Беларусь",
"category" : "entertainment",
"creatorID" : "1RXDSJzSEXakxvNdM41Ae3nbHN72",
"date" : 1477328400000,
"forFriends" : false,
"info" : "45",
"name" : "Test of date",
"uid" : "-KUSsl7RaL-dVoDCoSYT"
}
},
"FriendsOF" : {
"NuKweeGv8zTgt1Vi9RcU3i1u86U2" : {
"1RXDSJzSEXakxvNdM41Ae3nbHN72" : true
},
"m11EvlP19OSbEz8XYl2MsNCwGXX2" : {
"1RXDSJzSEXakxvNdM41Ae3nbHN72" : true
}
},
"Users" : {
"1RXDSJzSEXakxvNdM41Ae3nbHN72" : {
"email" : "*#gmail.com",
"name" : "Алексей Гвоздицкий",
"picture" : "*.jpg"
},
"NuKweeGv8zTgt1Vi9RcU3i1u86U2" : {
"email" : "*#gmail.com",
"name" : "Ольга Гвоздицкая",
"picture" : "*.jpg"
},
"m11EvlP19OSbEz8XYl2MsNCwGXX2" : {
"email" : "*#gmail.com",
"name" : "Егор Александров",
"picture" : "*.jpg"
}
}
}
I have a list of "events". Every "event" can be "forFiends" only (only if current user is in event creators "FriendsOF" list, then he can see this event. FriendsOF it's a whitelist). All availiable for current user events i want to represent in RecyclerView.
I am stucked. I can get all data snapshot and then filter on client side it. But it is not way of Jedi, because i load tonns of unnecessary data. Another solution is to deny acces to event if user should not see it. But i don't understand how to do it. My ref is mEventsRef = FirebaseDatabase.getInstance().getReference().child("Events").child("events"); And rule i can make for
"events":{
"$eventId":{".read":....}
}
So according to this guide i'll get empty recyclerView because of "error callback triggered with PERMISSION_DENIED"
Help me to solve my problem please!

Querying firebase with filtering data

So I have the Json in following format on firebase:
{
"30000000549656652" : {
"cast" : [ {
"src" : "https://encrypted-tbn1.gstatic.com/images",
"title" : "Hilary Duff (Samantha \"Sam\" Montgomery)"
}],
"channel_name" : "HBO",
"desc" : "After her .....",
"extras" : {
"initial" : "July 10, 2004 (Hollywood)",
"director" : "Mark Rosman",
"screenplay" : "Leigh Dunlap"
},
"genre" : "Thriller",
"lang" : "English",
"movie" : 1,
"prog_id" : 30000000549656652,
"prog_img" : "http://images."
"ratings" : {
"IMDb" : "5.9/10",
"Metacritic" : "25%",
"Rotten Tomatoes" : "11%"
},
"start" : 201607141800,
"stop" : 201607141700,
"title" : "Thrill A Cinderella Story",
"year" : "2004"
},
.....
}
I want to do the following in activity on my android app-
Query the node in which these JSON exist, then filter them such that i get all the results which have movies of one specific genre(e.g., Thriller) and the year is within five yrs less or five yrs more of the one i would pass in the query.
Like i would want to query to get all thriller movies whose "year" are between 2000 and 2009.
Can someone please help me to build such query for a json like this. Thanks!

Categories

Resources