How to display data that depends on other entity? - android

Having the following data:
"animals" : {
"a1" : {
"name" : "Dog"
},
"a2" : {
"name" : "Cat"
},
"a3" : {
"name" : "Cow"
}
},
"users" : {
"u1" : {
"favAnimals" : {
"a1" : true,
"a2" : true
},
"name" : "Danilo"
}
}
How can I display for the user, using the FirebaseListAdapter, the complete list of animals, highlighing user's favorite animals?
Is it possible to query and join them, to get a Database Reference that would watch for changes both in "/animals" and "/users/$uid/favAnimals" and return something like:
"animals" : {
"a1" : {
"name" : "Dog",
"fav" : true
},
"a2" : {
"name" : "Cat"
"fav" : true
},
"a3" : {
"name" : "Cow"
}
}

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.

Firebase security rules issue

I'm trying to restrict access to a particular groups if the user is not in the members list.
So this is my rule,
{
"rules": {
".read":"auth != null",
"groups": {
"$groupid":{
".read" : true,
".write" : "root.child('groupmembers').child($groupid).child('admins').child(root.child('users').child(auth.uid).child('username').val()).val()==true"
}
},
"groupchat":{
"$chatid":{
".read" : "root.child('groupmembers').child($chatid).child('members').child(root.child('users').child(auth.uid).child('username').val()).val()==true",
".write" : "root.child('groupmembers').child($chatid).child('members').child(root.child('users').child(auth.uid).child('username').val()).val()==true"
}
}
}
}
The first rule for "groups">"$groupid" works perfectly. But I'm getting problem with second rule for "groupchat"
DataStructure ex:
Group Chat structure
"groupchat" : {
"testinggroup" : {
"chat" : {
"-KiYN6RKZOyWI-qufWn3" : {
"message" : "Hey",
"timestamp" : 1493094660399,
"type" : "text",
"username" : "user2"
}
},
"lasttimestamp" : 1493094660674
}
}
Users Structure
"users":{
"ujciTL9oFKNylcgiGcdYqUxjcgA3" : {
"email" : "example#gmail.com",
"username" : "user1"
}
}
groupmembers structure
"groupmembers":{
"groupid":{
{
"admins" : {
"user1" : true,
"user3" : true
},
"members" : {
"user1" : true,
"user2" : true,
"user3" : true,
"user4" : true
}
}
}
}
groups structure
"groupid"{
{
"category" : "group category",
"creator" : "creator uid",
"desc" : "group desc",
"id" : "groupid",
"image" : "url",
"name" : "groupname"
}
}
Operation ex:
FirebaseDatabase.getInstance()
.getReference()
.child("groupchat")
.child(j)
.child("lasttimestamp")
.setValue(ServerValue.TIMESTAMP);
So to debug the errors
I added "myusername" in place of root.child('users').child(auth.uid).child('username').val()
and it's working.
But in the previous rule("For groups child") I added the same thing and it was working.
I don't know why I'm getting error.

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!

Order data by child node's value - Firebase

I'm trying to retrieve all recipes favorited by a user using this code, but no data is retrived
recipesQuery = mDatabase.child("recipes").orderByChild("favoritedBy").equalTo(getId());
This is my Structure:
{
"-KNnrgEmF8qCpsWiIMW4" : {
"favoriteCount" : 4,
"favoritedBy" : {
"0ZtxMXZ8iDV4u0POxu8n6cIwCX33" : true
},
"name" : "Recipe 1",
"recycleCount" : 0,
},
"-KNvq6Ts8RYxc0-O3B2t" : {
"favoriteCount" : 2,
"favoritedBy" : {
"0ZtxMXZ8iDV4u0POxu8n6cIwCX33" : true
},
"name" : "Recipe 2",
"recycleCount" : 0,
}
}
If I remove the .equalTo() method all data is retrieved, but thats not what I want.
What am I doing wrong?
There's currently no method to filter a query based on other objects than String, Boolean, or Double.
What I suggest is to restructure your database to something like this
{
"users": {
"userId1" : {
"name" : "User1",
"favorites": {
"-KNnrgEmF8qCpsWiIMW4" : true,
"-KNvq6Ts8RYxc0-O3B2t" : true
}
},
"userId2" : {
"name" : "User2",
"favorites": {
"-KNvq6Ts8RYxc0-O3B2t" : true
}
}
},
"recipes": {
"-KNnrgEmF8qCpsWiIMW4" : {
"favoriteCount" : 4,
"name" : "Recipe 1",
"recycleCount" : 0,
},
"-KNvq6Ts8RYxc0-O3B2t" : {
"favoriteCount" : 2,
"name" : "Recipe 2",
"recycleCount" : 0,
}
}
}
Then it's easier to get the recipes favorited by specific user.
mDatabase.child("users").child(userid).child("favorites")

Firebase Retrieve Limited Messages by Auto assigned timestamp

I wish to retrieve only the top 50 messages a user has within the database, with schema:
"individualMessages" : {
"99e4989b-a046-4c5f-9478-5ebd8bdc3ded" : {
"a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" : {
"-KBUjngi9JStE-k4RMUJ" : {
"from" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd",
"messageText" : "hey",
"timeSent" : "2016-02-26 17:40:46"
},
"-KBYhsRONfGxVI7Ysb3F" : {
"from" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd",
"messageText" : "pool",
"timeSent" : "2016-02-27 12:10:52"
}
},
"fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" : {
"-KBcYtQ5gD-drFZqz_MU" : {
"from" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de",
"messageText" : "ouu",
"timeSent" : "2016-02-28 10:46:52"
},
"-KBcYw24M-9-7H5A3czD" : {
"from" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de",
"messageText" : "gsf",
"timeSent" : "2016-02-28 10:47:03"
}
However, simply using:
individualMessageMyPath = myFeastFirebase.child("individualMessages").child(.....
getTop50Messages = individualMessageMyPath.limitToLast(5);
getTop50Messages.orderByChild("timeSent").addChildEventListener(mainMessagingListener);
Returns all messages on that node.
Reviewing the documentation this should work, however it does not.
What is missing?

Categories

Resources