Firebase Retrieve Limited Messages by Auto assigned timestamp - android

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?

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.

"Can't convert object of type java.lang.String to type com.android.projectrc.Listing" when using Firebase RecyclerAdapter

I'm attempting to load a specific set of data from Firebase (a user searches for a city and we get the nearest locations to it and store it in an array) and I'm having an issue populating a recyclerview with my results. I get this error: com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.android.projectrc.Listing - which seems to indicate that I'm getting Strings instead of a "Listing" - which makes sense considering the database is structured like so:
Listings
{
"-L01KIjNtpgq2H0VopCn" : {
"LevelOfQuestionnaireCompletion" : true,
"ListingData" : {
"AircraftHouseRules" : {
"Pricing" : "100",
"SuitableForPets" : "Yes",
"SuitableForSmoking" : "No",
"SuitableForchildren" : "Yes"
},
"BasicInfo" : {
"AirportCode" : "ATL",
"City" : "Atlanta",
"Country" : "United States",
"ModelPlane" : "Learjet",
"NameOfListing" : "Roomy 4- Seater",
"NumberOfGuests" : "0",
"Owner" : "WdWB80uRtUPRF2sOFH5uJr2Tfu12",
"PrimarilySetupForGuests" : "Yes",
"State" : "Georgia",
"Street" : "6000 N Terminal PKWY",
"ZipCode" : "30320"
},
"DetailedInformation" : {
"IdealGuests" : "Big groups",
"ImageRef" : {
"-L01KUEWb8trSidSTzgW" : "5051E390-7FD5-4CEF-9C1B-EB959C13A4C2",
"-L01KUEWb8trSidSTzgX" : "E2BCA170-0F7B-43B1-BAC6-BEBBB6DEF630"
},
"SummaryOfPlane" : "Give us a brief description of your plane..."
}
}
},
"-L035Y5c_i88HW-BOlbQ" : {
"LevelOfQuestionnaireCompletion" : true,
"ListingData" : {
"AircraftHouseRules" : {
"Pricing" : "1000",
"SuitableForPets" : "Yes",
"SuitableForSmoking" : "No",
"SuitableForchildren" : "Yes"
},
"BasicInfo" : {
"AirportCode" : "ATL",
"City" : "Mableton",
"Country" : "United States",
"ModelPlane" : "Learjet",
"NameOfListing" : "Roomy 7 Seater Plane",
"NumberOfGuests" : "0",
"Owner" : "DjElZ1UT7jOOS23kjGwIr6lP5u22",
"PrimarilySetupForGuests" : "Yes",
"State" : "Georgia",
"Street" : "1368 Foxhall Place",
"ZipCode" : "30126"
},
"DetailedInformation" : {
"IdealGuests" : "Big groups",
"ImageRef" : {
"-L035nMB96ykxHolPYSE" : "B3488600-EFB8-4A7B-B60B-B595E4AFB52E"
},
"SummaryOfPlane" : "Give us a brief description of your plane..."
}
}
},
"-L0CiG0yGBvC0bHRjz3W" : {
"LevelOfQuestionnaireCompletion" : false,
"ListingData" : true
}
}
I'm only interested in the information under "BasicInfo" and have made a class to get the information relevant to the user:
Listing.kt
data class Listing(
val ModelPlane: String = "",
val AirportCode: String = "",
val City: String = "",
val State: String = "")
The relevant code is as follows:
ListingAdapter.kt
class ListingAdapter(listingModel: Class<Listing>, modelLayout: Int, viewHolderClass: Class<ListingHolder>, dbRef: DatabaseReference) :
FirebaseRecyclerAdapter<Listing, ListingHolder>(listingModel, modelLayout, viewHolderClass, dbRef) {
override fun populateViewHolder(viewHolder: ListingHolder?, model: Listing?, position: Int) {
viewHolder!!.planeModel.text = model!!.ModelPlane
viewHolder.airportCode.text = model.ModelPlane
}
}
ListingHolder.kt
class ListingHolder(v: View) : RecyclerView.ViewHolder(v) {
var planeModel: TextView = v.listing_plane_model
var airportCode: TextView = v.listing_airport_code
}
And the code that glues it all together:
for (listing in keyList) {
val listingReference = mDatabaseReference
.getReference("Listings/$listing/ListingData/BasicInfo")
listingReference.keepSynced(true)
search_results.adapter = ListingAdapter(Listing::class.java, listings_view_layout, ListingHolder::class.java, listingReference)
}
I'm pretty sure there's something I missed (or messed up) in creating my Adapter class, but I'm not entirely sure what, as all the guides I've looked at seem to follow the same pattern I've done. ($listing corresponds to the unique ID given to every listing in the database e.g. "-L0CiG0yGBvC0bHRjz3W")
For anyone who comes by later - I managed to solve this issue by moving up one level in my DB reference (going from Listings/$listing/ListingData/BasicInfo to Listings/$listing/ListingData/) it seems Firebase was smart enough to grab the specific information I needed on its own (instead of needing me to specifically tell it where it is), everything works fine now!

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!

Firebase Android Database

I am making an app that should include chat. I would like to display conversations of the current user. I am not sure how to get only chats of the current user. This is my structure of database.
"chats" : {
"-KWYiJiFwE6miPNkKPe0" : {
"chatPartner1" : {
"id" : "rtg3ru7zNYQQp9LA484VIG5rItl1",
"name" : "ghjg",
"photo" : ""
},
"chatPartner2" : {
"id" : "rtg3ru7bzwwewNYQwwewetegb",
"name" : "petra",
"photo" : ""
},
"id" : "-KWYiJiFwE6miPNkKPe0",
"lastMessage" : "dhjcd",
"timestamp" : 1479141836276
}
This json represents storing message for specified chats according to its id.
"messages" : {
"-KWYiJiFwE6miPNkKPe0" : {
"-KWYiJiPWR3n_YcvokCm" : {
"senderId" : "rtg3ru7zNYQQp9LA484VIG5rItl1",
"text" : "dhjcd",
"timestamp" : 1479141836276
}
}
I would need to check if the chatPartner 1 or 2 contains id of the current user. Or do you know about better way to store chats?
Thanks

How to display data that depends on other entity?

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"
}
}

Categories

Resources