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
Related
The code
This is our code, we just want to display the current user's key, that's it so how should we do that.
Currently, the code gives the output of all the keys and not the current user key.
As output, we are getting the values: Asif, Test24, and Vaishnavi in the variable key
The image is of the Realtime Database The image of Realtime Database
To solve this issue, you need to use a query. In Kotlin, the code should look like this:
val uid = FirebaseAuth.getInstance().currentUser?.uid
val db = FirebaseDatabase.getInstance().reference
val usersRef = db.child("Users")
val queryByUid = usersRef.orderByChild("uid").equalTo(uid)
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (ds in dataSnapshot.children) {
val key = ds.getKey()
Log.d("TAG", key)
}
}
override fun onCancelled(error: DatabaseError) {
Log.d("TAG", error.getMessage()) //Never ignore potential errors!
}
}
queryByUid.addListenerForSingleValueEvent(valueEventListener)
If for example,e the authenticated user is Asif, then the result in the logcat will be:
KYGf ... uSP2
Always remember to add all necessary keys when you create a reference. Never use .child(""), which is an empty string.
I need to order items from firebase by timestamp. Then I would like to sum the total price so far I have managed to list the products inside a recyclerview, but they are not ordered
private fun getProductData(){
dref = FirebaseDatabase.getInstance().getReference("Products")
dref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()){
for (productSnapshot in snapshot.children){
val product = productSnapshot.getValue(ProductData::class.java)
productList.add(product!!)
}
prodList.adapter = productAdapter
}
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(activity, error.message, Toast.LENGTH_SHORT).show()
}
})
if someone can help me order them, and if possible show me how to find the sum of the price. I have read many docs but they don't ring the bell.
To order the child nodes you'll want to use a query as shown in the documentation on ordering and filtering data:
dref = FirebaseDatabase.getInstance().getReference("Products")
val query = dref.orderByChild("prodTime")
query.addValueEventListener(object : ValueEventListener {
...
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.
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
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>
...