why firebase display data randomly and unordered? - android

i don't know why when i get my data from the firebase will Display on the listview random and unordered i tryed many time with out any result
there is no problem with the data on fire base but on the phone display.
fun AddToList(){
mRef.child("MyPosts").child("TEST").addValueEventListener(object
:ValueEventListener{
override fun onCancelled(p0: DatabaseError?) {
Toast.makeText(this#NewsList,"Error",Toast.LENGTH_SHORT).show()
}
override fun onDataChange(datap0: DataSnapshot?) {
try {
var td = datap0!!.value as HashMap<String,Any>
MyList.clear()
for (key in td.keys){
var data = td[key] as HashMap<String,Any>
MyList.add(ForList(
data["pic"] as String
,data["txt1"] as String
,data["txt2"] as String
,data["m1"] as String
,data["m2"] as String
,data["m3"] as String
)
)
adapter!!.notifyDataSetChanged()
}
}catch (ex:Exception){
Log.e("MyAPP","Error on you app 0000",ex)
}
}
})
}

You're not asking for the data in any specific order: mRef.child("MyPosts").child("TEST").addValueEventListener(.... If you want the data in a specific order, you will have to specify that. For example, to get the child nodes in the order of their keys:
mRef.child("MyPosts").child("TEST").orderByChild().addValueEventListener(...
With this the DataSnapshot that is passed into onDataChange will contain the data in the order of the keys. But if you then get the value like this datap0!!.value as HashMap<String,Any> you are dropping any ordering information, since a map can't maintain the information about the ordering of the child nodes.
To process the data in the order you requested you should look over the child nodes of the DataSnapshot with:
override fun onDataChange(snapshot: DataSnapshot?) {
MyList.clear()
for (child: DataSnapshot? in snapshot.getChildren()) {
var data = child!!.value as HashMap<String,Any>
...

Related

how to get all child with specific value from Firebase android kotlin?

I want to get just color item in the image from all user in my database. I try this
private fun setListPersonOfferService(){
val database = FirebaseDatabase.getInstance()
val userIdReference = database.getReference("user personal data").child("Country")
val userFilterListener = object : ValueEventListener {
override fun onCancelled(databaseError: DatabaseError) {
// handle error
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
val listTest = dataSnapshot.children.map { it.getValue(HomePageModel::class.java)!! }
itemAdapter = ItemAdapterHomePage(context ?: return,
listTest as ArrayList<HomePageModel>
)
itemAdapter?.onItemClick = {
Supplier.serviceList[it].state = !Supplier.serviceList[it].state
itemAdapter?.notifyDataSetChanged()
Toast.makeText(context, "go to speck", Toast.LENGTH_LONG).show()
}
recyclerView_homePage.apply {
layoutManager = LinearLayoutManager(context)
adapter = itemAdapter
}
}
}
userIdReference.addListenerForSingleValueEvent(userFilterListener)
}
class HomePageModel(var lastName: String?=null,
var town: String?=null,
var faculty: String?=null,
var languageOfStudy: String?=null )
if i change Reference to the specific directory .child("Turcia").child("Adana").child("Çukurova University").child("Faculty of Business") it works, but i want to get from all user.
You'll need to navigate over the dataSnapshot in your onDataChange to get to the correct child nodes.
To navigate a DataSnapshot object you have two main approaches:
You already know the key of the child you want to access, in which case you use the child() method to access that specific child node. For example, you could read the marked child in the JSON with dataSnapshot.child("Turcia/Adana/Çukurova University/Faculty of Business").children.map, similarly to what you already tried on the reference.
You don't know the key of the child nodes, in which case you loop over the getChildren() property of the snapshot. For an example of the latter, see the Firebase documentation on listening for value events on a list of children.
I think you're looking for the second approach here, but in any case you're dealing with DataSnapshots, there are the ways to get at the data in there.

how do i retrieve data from firebase realtime database using kotlin

Im trying to pull data from firebase realtime database but i'm not sure how to pull more than one data piece at the same time if its possible.
so this is what the database looks like:
so far i have managed to be able to print out all of these values in the following way:
private fun getData() {
var currentUid = mAuth.currentUser?.uid
val myRef = database.getReference("User-following").child(currentUid!!)
myRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val children = dataSnapshot.value
Log.e("Database", "value = $children")
}
override fun onCancelled(error: DatabaseError) {
Log.e("Database", error.toString())
}
})
}
when it prints the value of children i get all 5 in the following format:
E/Database: value = {-MLwcu81dicGo1NezqJD=1, -MLwcwBjdjRo-vgSkEjR=1, -MLwep1w5z4DfGeabx0d=1, -MLw_sc6aHPxPpGBIpCL=1, -MLwdqVch3iDr3GXylln=1}
how to i return each individual id so that i can use it to retrieve the data that corresponds to each id?
To access the individual child nodes under the snapshot you retrieved, you'll want to loop over its children.
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (childSnapshot in dataSnapshot.children) {
Log.i("Database", "child key = $childSnapshot.key")
}
}
Also see the Firebase documentation on listening to value events.

how to check if firebase have value1 and value2 exist

I'm trying to do the following in my Android application using Kotlin :
I have the Firebase data structure as shown in this image:
The user is able to choose 2 stations from the stations included in the data, either as "start_station", "end_station" or "station_number".. in the next function am trying to take the user's selections and check if both are encluded in the same line.
private fun fetchingLinesData(
theEndStation: String,
theStartStation: String,
) {
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("line")
myRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
toast(getString(R.string.could_not_find_a_way))
}
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach{
//Here should be the line that checks if both data exist
}
}
})
}
Tried using This hasChild Method but it wasn't right.
Try to convert your response to HashMap and search using containsValue
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach {
//Here should be the line that checks if both data exist
if(it.hasChildren()) {
val stationLines = it.value as HashMap<String, Any>
val validStart = stationLines.containsValue(theStartStation)
val validEnd = stationLines.containsValue(theEndStation)
...
}
}
}
You can do a query:
myRef.orderByChild("end_station").equalTo(theEndStation).addValueEventListener
This will retrieve the data according to the query, then inside onDataChange() after the forEach you can do the following:
if(p0.exists()){
// retrieve data here
}
Using exists() you can check if the datasnapshot exists.
This query will only check for end_station, if you want to check both, then after the query inside the if statement you can retrieve the first_station:
if(p0.exists()){
val firstStation = it.child("start_station").value
And check if firstStation is equal to theStartStation

How to sort items of recycerview according to external conditions

I have a simple app where user set their DOB and the app calculates the days remaining for next birthday.
I am using firebase to store data and when fetching data I get DOB from database and perform calculation to find days remaining for next birthday. Just for note days remaining is calculated after fetching it is not stored in database.
So what I want is After fetching DOB and calcultaing remaing days I want to show the data in Recycler View in the ascending order of the remaing days.
How can I do that?
Databasemodel.kt
data class Databasemodel(val uid:String, val name:String, val dob:String) {
constructor():this("",",","")
}
Mainactivity.kt
lateinit var bdayList: MutableList<Databasemodel> //I have initialized it later
val ref = FirebaseDatabase.getInstance().getReference("BirthdayPersons")
ref.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
bdayList.clear()
for (iterator in p0.children) {
val bday=iterator.getValue(Databasemodel::class.java)
bdayList.add(bday!!)
}
row_recycle_actual.layoutManager = LinearLayoutManager(applicationContext)
row_recycle_actual.adapter=RecyclerAdapter(bdayList)
}
}
})
After
for (iterator in p0.children) {
val bday=iterator.getValue(Databasemodel::class.java)
bdayList.add(bday!!)
}
you should sort the list by desired predicate, you may do it with sortBy in Kotlin:
//assuming you have "remainingDays" or similiar field in your model
bdayList.sortBy { dbmodel -> dbmodel.remainingDays}
then you may pass it to the RecyclerView
row_recycle_actual.adapter=RecyclerAdapter(bdayList)

Firebase getValue returns as a HasMap with the key regardless of how I ask for it

Some of my data is stored in Firebase as like in the screen shot bellow, under a parent called "votes":
I am trying to pull the value only (-1) but keep getting the whole HashMap.
The key in this case is represented in my code as a variable called inititorId and postVotesSnapshot represents the parent snapshot the holds many children as in the screen shot I've attached.
I've tried:
postVotesSnapshot.child(initiatorId).value
or
postVotesSnapshot.child(initiatorId).getValue(Integer::class.java)
And both got me the whole HashMap with the key causing a crash because I need the value to be an Int.
I've tried:
val valueHash = postVotesSnapshot.child(initiatorId).getValue(HashMap::class.java)
val myValue = valueHash[initiatorId]
But that doesn't work wither.
I'm not sure what has gone wrong as the code worked perfectly before with the first option I've mentioned and today it suddenly throws an error at me.
Here's the complete Listener:
val refVotes = if (postType == 0) {
FirebaseDatabase.getInstance().getReference("/questions/$mainPostId/main/votes")
} else {
FirebaseDatabase.getInstance().getReference("/questions/$mainPostId/answers/$specificPostId/votes")
}
refVotes.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(postVotesSnapshot: DataSnapshot) {
setVotesCount(specificPostId, mainPostId, votesView, postType)
if (postVotesSnapshot.hasChild(initiatorId)) {
val voteValue = postVotesSnapshot.child(initiatorId).getValue(Integer::class.java) //this line is the problematic one
//I do stuff
}
}
})
}
Try the following:
val ref = firebase.child("posts")
ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot?) {
val id = dataSnapshot.child(initiatorId).getValue(Integer::class.java)
}
override fun onCancelled(error: FirebaseError?) {
println(error!!.message)
}
})
Assuming, you have the following database:
posts
VMQPBq6YK3bJ12xIjGeTHsqaJC2 : -1
Here the dataSnapshot will be at child posts, then you need to attach the addListenerForSingleValueEvent and access the child initiatorId. Also assuming that initiatorId is equal to VMQPBq6YK3bJ12xIjGeTHsqaJC2

Categories

Resources