How to get data from firebase ( datasnapshot)? - android

I am using firebase database and I had stored the user information in the database ( realtime ) and I want to get the information into my user profile UI in my app
Now when I use snapshot, I don't know how to get the information of it
Any help please?
val userId = authRef.currentUser?.uid
val currentUser = dataRef.getReference("/Users/$userId")
currentUser.addValueEventListener(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
// I need to get data from here ( userDisplayName , userPhone, userCity, userCountry)
}
})

Try this
val userId = authRef.currentUser?.uid
val currentUser = dataRef.getReference
val userchild = currentuser.child("Users").child("userId")
userchild.addValueEventListener(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
val userDisplayName = p0.child("userDisplayName").getValue(String::class.java)
val userPhone = p0.child("userPhone").getValue(String::class.java)
val userCity = p0.child("userCity").getValue(String::class.java)
}
})
Must type exect spellings of Users, UserId and other childs. and To these values to textview in the Ui add
TextView.setText=variable abc
Your Mistakes in codes.You have not taken correct data snapshot which i have updated.

To retrieve the data try the following:
override fun onDataChange(p0: DataSnapshot) {
// I need to get data from here ( userDisplayName , userPhone, userCity, userCountry)
val userDisplayName = p0.child("userDisplayName").getValue(String::class.java)
val userPhone = p0.child("userPhone").getValue(String::class.java)
val userCity = p0.child("userCity").getValue(String::class.java)
}
})

Related

How can I populate my RecyclerView from multiple nodes of my Firebase Realtime Database?

I am looking for a way to populate my RecyclerView. I know how to populate a RecyclerView from a single node of my database but I wonder how can I get data from multiple nodes. In my app the user can select multiple hobbies. And I want to populate a recycler view depending which hobbies the user has selected.
Here is a picture of my user node from my database
As you can see my user has selected the hobbies Caffe's,Camping,Hiking
I have a node called Locations and there a six child nodes Caffe's,Camping,Hiking,Museums,Night life and restaurants. Here is my Locations node
I get users hobbies from this code block
val currentuid = FirebaseAuth.getInstance().currentUser!!.uid
val getCurrentUserHobbies =
FirebaseDatabase.getInstance().getReference("users/$currentuid/hobbies")
getCurrentUserHobbies.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val value = snapshot.getValue(String::class.java)
val valueAsString = value.toString()
if (valueAsString.contains("Hiking")){
}
}
override fun onCancelled(error: DatabaseError) {
}
})
If I want to get my recycler view to show all Hiking locations I do this:
val adapter = GroupAdapter<GroupieViewHolder>()
val hikingRef = FirebaseDatabase.getInstance().getReference("Locations/Hiking")
hikingRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
for (snap in snapshot.children) {
val recommendItems = snap.getValue(RecommendationsClass::class.java)
if (recommendItems != null) {
adapter.add(RecommendationsAdapter(recommendItems))
}
}
recommendationsRecyclerView.adapter = adapter
}
override fun onCancelled(error: DatabaseError) {
}
})
Now if the user has selected hiking and camping for example. I want my recycler view to show all locations from nodes Locations/Hiking and Locations/Camping. I tried multiple but nothing works. I am not going to write them here because it will take too much space. I am trying to keep my question as simple as possible.
Thanks in advance!
I unfortunately could not find any possible solution how to make it work. I had to do something different. What I did I copied sub nodes from my Locations node and put them in users/currentuid/Recommendations depending which hobbies my current user has.
Here is the code snipped that does that:
val currentuid = FirebaseAuth.getInstance().currentUser!!.uid
val getCurrentUserHobbies = FirebaseDatabase.getInstance().getReference("users/$currentuid/hobbies")
getCurrentUserHobbies.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val value = snapshot.getValue(String::class.java)
val valueAsString = value.toString()
if (valueAsString.contains("Caffe's")) {
val ref = FirebaseDatabase.getInstance().getReference("Locations/Caffe's/")
ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (snap in dataSnapshot.children) {
val data = dataSnapshot.value
val newData = mapOf("Recommendations/${dataSnapshot.key}" to data)
FirebaseDatabase.getInstance().getReference("users")
.child(currentuid).updateChildren(newData)
}
}
override fun onCancelled(databaseError: DatabaseError) {
// Handle error
}
})
}
if (valueAsString.contains("Camping")) {
val ref = FirebaseDatabase.getInstance().getReference("Locations/Camping/")
ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (snap in dataSnapshot.children) {
val data = dataSnapshot.value
val newData = mapOf("Recommendations/${dataSnapshot.key}" to data)
FirebaseDatabase.getInstance().getReference("users")
.child(currentuid).updateChildren(newData)
}
}
override fun onCancelled(databaseError: DatabaseError) {
// Handle error
}
})
}
if (valueAsString.contains("Hiking")) {
val ref = FirebaseDatabase.getInstance().getReference("Locations/Hiking/")
ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (snap in dataSnapshot.children) {
val data = dataSnapshot.value
val newData = mapOf("Recommendations/${dataSnapshot.key}" to data)
FirebaseDatabase.getInstance().getReference("users")
.child(currentuid).updateChildren(newData)
}
}
override fun onCancelled(databaseError: DatabaseError) {
// Handle error
}
})
}
}
override fun onCancelled(error: DatabaseError) {
}
})
What the code above does it checks if caffe's camping and hiking exists in my users/currentuid/hobbies node. If it does it copies the data from Locations and puts it in users/currentuid/Recommendations.
Note: I also have to check for remaining three hobbies. I only put three of them for testing purposes.
Here is also an image to show what I did
After this I only looped through my Recommendations node and added all the locations to my recycler view with this code snippet:
val recommendedLocations = FirebaseDatabase.getInstance().getReference("users/$currentuid/Recommendations")
recommendedLocations.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
for (parentSnapshot in snapshot.children) {
for (childSnapshot in parentSnapshot.children) {
val recommendItems = childSnapshot.getValue(RecommendationsClass::class.java)
if (recommendItems != null) {
adapter.add(RecommendationsAdapter(recommendItems))
}
}
}
recommendationsRecyclerView.adapter = adapter
}
override fun onCancelled(error: DatabaseError) {
}
})

How to get specific data from Firebase with Kotlin

So I have a movie app. If I liked the movie I'm gonna save its id to firebase. And my goal is to get all movie_id's and display them on screen.
This is the saving code.
firebaseDb.getReference("Users").child(uid).child("movie")
.push().child("movie_id")
.setValue(args.movie.id)
And this is the firebase display
So how to get all movie_id's? I tried this but nothing happened.
firebaseDb.getReference("Users").child(uid).child("movie").addValueEventListener(object :
ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val map: Map<String, Any> = snapshot.getValue() as Map<String, Any>
val mapSize = map.keys.size
for (i in 1..mapSize) {
val keys = map.filterKeys { it == map.keys.toTypedArray()[i - 1] }
}
}
If want to create a list of movie IDs, then use the following lines of code:
val uid = FirebaseAuth.getInstance().currentUser?.uid
val db = FirebaseDatabase.getInstance().reference
val movieRef = db.child("Users").child(uid).child("movie")
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val movieIds = mutableListOf<String>()
for (ds in dataSnapshot.children) {
val movieId = ds.child("movie_id").getValue(String::class.java)
movieIds.add(movieId)
}
Log.d("TAG", movieIds.size.toString())
}
override fun onCancelled(error: DatabaseError) {
Log.d("TAG", error.getMessage()) //Never ignore potential errors!
}
}
movieRef.addListenerForSingleValueEvent(valueEventListener)
The result in the logcat will be:
2
As I only see two movies in the screenshot.

How to update Firebase Data using Constructor class

I want to update the Name-based from User Input NIK then show the data to the field and by pressing the update button it will update the data inside the Database.
I'm using this Constructor Class :
import com.google.firebase.database.Exclude
import com.google.firebase.database.IgnoreExtraProperties
#IgnoreExtraProperties
class DatabaseModelUpdate(
var nama : String = ""
) {
#Exclude
fun toMap(): Map<String, Any?> {
return mapOf(
"nama" to this.nama
)
}
}
and my source code is :
val nama = findViewById<EditText>(R.id.editNama).text.toString().trim()
val model = DatabaseModelUpdate(nama)
val post = model.toMap()
var query = reference.orderByKey().equalTo(NIK)
query.addListenerForSingleValueEvent(object : ValueEventListener {
#SuppressLint("SetTextI18n")
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists()) {
for (userSnapshot in dataSnapshot.children) {
var keys = userSnapshot.ref.key.toString()
val updates = hashMapOf<String, Any>(
"/Users/$keys" to post
)
userSnapshot.ref.updateChildren(updates)
}
}
My JSON :
But, after I pressed the Update Button nothing change.
UPDATE
Codes:
private fun updating() {
val NIK = findViewById<EditText>(R.id.inputNik).text.toString().trim()
val nama = findViewById<EditText>(R.id.editNama).text.toString().trim()
var query = reference.orderByChild("nik").equalTo(NIK)
query.addListenerForSingleValueEvent(object : ValueEventListener {
#SuppressLint("SetTextI18n")
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists()) {
for (userSnapshot in dataSnapshot.children) {
var keys = userSnapshot.ref.key.toString()
val updates = hashMapOf<String, Any?>(
"Users/$keys/nama" to nama
)
dataSnapshot.ref.updateChildren(updates)
Database :
The codes just making a new nodes instead updating the data
UPDATES 2
using
"nama" to nama
database :
To update the "nama" property of the object which has the key equal to "NIK", you can directly point to that particular property and set the new name as shown in the following lines of code:
val query = reference.orderByKey().equalTo(NIK)
val listener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (ds in dataSnapshot.children) {
ds.child("nama").getRef().setValue("newNama")
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("TAG", databaseError.getMessage()) //Don't ignore potential errors!
}
}
query.addListenerForSingleValueEvent(listener)
So there is no need at all to create any additional classes for a simple update.
Edit:
You might also consider trying this:
for (userSnapshot in dataSnapshot.children) {
val updates = hashMapOf<String, Any>(
"nama" to "newNama"
)
userSnapshot.ref.updateChildren(updates)
}

Display data from Firebase Realtime Database

Created next structure in my database, and now want to display data in my list
Tried to add next code in onViewCreated:
databaseReference = FirebaseDatabase.getInstance().reference
val wordsRef = databaseReference?.child("talk-6e3c0")?.child("words")
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
topWordsList.clear()
for (wordsSnapshot in dataSnapshot.children) {
val topWord = wordsSnapshot.getValue(TopWord::class.java)
topWord?.let { topWordsList.add(it) }
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("some", "Error trying to get targets for ${databaseError.message}")
}
}
wordsRef?.addListenerForSingleValueEvent(valueEventListener)
Method onDataChanged was called, but i can't get name for example.
My model:
data class TopWord(
val name: String = "",
val description: String = ""
)
You aren't getting something because you are adding the name of your project as a child in the reference and there is no need for that. So please change the following line of code:
val wordsRef = databaseReference?.child("talk-6e3c0")?.child("words")
to
val wordsRef = databaseReference?.child("words")
I just removed the call to .child("talk-6e3c0")?.

Display target data from firebase

I display a list of my targets in fragmentA, when I click on one of them, I pass the guid of this target to the fragmentB
After that, I try in the fragmentB display the data of this target for this guid:
private fun fetchTarget(guid: String) {
val uid = firebaseUser!!.uid
// Attach a listener to read the data at the target id
databaseReference?.child("targets")?.child("users")
?.child(uid)?.child("targets")?.child(guid)?.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val data = dataSnapshot.value as? HashMap<String, String>?
val name = data?.get("name") ?: ""
val description = data?.get("description") ?: ""
if (name.isEmpty()) Log.d("some", "nameIsEmpty")
else updateViewsContent(name = name, description = description)
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("some", databaseError.message)
}
})
}
Here I get the guid: -LmfEVnwgqCUqt7beHDg
And in my console i have next structure:
Unfortunately I can't display data of target, though like all the chains I installed
Q: How i can download -LmfEVnx-y7c3oh8_U9F ?
To display the data that belongs to a single guid, you should use a query and then iterate through the DataSnapshot object like in the following lines of code:
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val rootRef = FirebaseDatabase.getInstance().reference
val targetsRef = rootRef!!.child("targets").child("users").child(uid).child("targets")
val query = targetsRef.orderByChild("guid").equalTo("-LmfEVnwgqCUqt7beHDg")
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (ds in dataSnapshot.children) {
val target = ds.getValue(Target::class.java)
Log.d(TAG, target.name)
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
}
}
query.addListenerForSingleValueEvent(valueEventListener)
The result in the logcat will be:
fgg
You are not getting any data because to get above data your guid value in query should be "-LmfEVnx-y7c3oh8_U9F" but you are passing "-LmfEVnwgqCUqt7beHDg".
You can try below query to get above data:
val uid = firebaseUser!!.uid
// Attach a listener to read the data at the target id
databaseReference?.child("targets")?.child("users")?.child(uid)?.child("targets")?.orderByChild("guid").equalTo(guid)?.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val data = dataSnapshot.value as? HashMap<String, String>?
val name = data?.get("name") ?: ""
val description = data?.get("description") ?: ""
if (name.isEmpty()) Log.d("some", "nameIsEmpty")
else updateViewsContent(name = name, description = description)
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("some", databaseError.message)
}
})

Categories

Resources