I am trying to fetch data from firebase based on userId, when the user logged in I need to show his profile details based on its id but I am unable to fetch it. Any help?
auth = FirebaseAuth.getInstance()
databaseRef = FirebaseDatabase.getInstance().getReference("Users/")
databaseRef.addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
//I want first_name and all other details of users
Log.e("first_name", snapshot.child(uid).getValue(String::class.java))
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
One problem is that you don't seem to initialize uid anywhere. So that should be:
auth = FirebaseAuth.getInstance()
uid = auth.currentUser.uid
Also see the Firebase documentation on getting the current user.
Next is not necessarily a bug, but definitely an optimization you'll want to do. Right now you read the entire Users node into your Android app, to then only get a value from /Users/$uid. As you add more users to the database, this is not going to scale.
What you'll want to do instead, is only load the node for the current user from the database with:
databaseRef = FirebaseDatabase.getInstance().getReference("Users/")
var userRef = databaseRef.child(uid)
userRef.addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
Log.e("first_name", snapshot.getValue(String::class.java))
}
...
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.
How i can read just color item in the image with out all data sub child?
I try this
val database = FirebaseDatabase.getInstance()
val personalDataReference = database.getReference("user personal data")
val messageList = ArrayList<String>()
personalDataReference.addValueEventListener(object : ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot){
messageList.add(dataSnapshot.value.toString())
}
override fun onCancelled(error: DatabaseError) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException())
}
})
but it get all the data
Consider using the Firebase Kotlin SDK by GitLive.
This library is also multi-platform, so the same code can be used on both Android and on iOS via Kotlin Multiplatform Mobile.
The code to read the keys from Firebase realtime database would look like this:
val keys = db.reference("/path/to/user personal data")
.valueEvents
.first()
.children
.mapNotNull { it.key }
Note here that valueEvents is a Kotlin Flow of DataSnapshot, therefore you can do more than simply taking the first snapshot and mapping it to a list as shown above. See the Flow documentation.
The things you've marked yellow are known as keys in Firebase terms.
To get a list of only the keys, you can do:
personalDataReference.addValueEventListener(object : ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot){
for (childSnapshot in dataSnapshot.children) {
messageList.add(childSnapshot.key)
}
}
Note that this will still read all JSON from the database, but the list will only contain the keys.
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.
I'm building a chat app and this is what my Database looks like:
So, I currently have a users node as well as a chats node.
The users node saves the last last login date and the chats Ids that the user is currently part of. In the chats node, it is saved the User Ids that make part of the conversation as well as the messages which have an Id, Content, Send Date, and User who sent.
Currently I am building the activity where it is displayed the conversations that the user is part of (using a recyclerview).
To be able to know what conversations the user is part of, instead of retrieving all conversations, I retrieve the chats ids that are in the user node and I put them all in an ArrayList<String>.
The code that retrieves those Ids and puts them in the ArrayList is this:
db.addListenerForSingleValueEvent(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach{
chatsId.add(it.key.toString()) // ChatsId is the ArrayList<String>
}
getChats2()
}
})
And this code works like a charm.
The problem comes when I try to query the chats node just to retrieve the chat that has the value equal to the values retrieved in the code above.
** That code is implemented in the getsChat2() **:
db = FirebaseDatabase.getInstance().getReference("chats")
// For each chatId, queries the DB to find the chat reference
chatsId.forEach {
val query = db.equalTo(it)
query.addValueEventListener(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach {it2->
println("Do something")
// Do something with the chat reference
}
}
})
}
The problem is, even if there is a node with the same value as the chatsId variable, the println("Do Something) never actually prints.
It's a bit hard to understand what you're trying to do, but my educated guess is that you're missing an orderByKey() call:
val query = db.orderByKey().equalTo(it)
When you don't call any orderBy...() method, the nodes are sorted on their priority. That's a left-over from the early days of the API that has very little practical use, so these days it mostly means that you must call orderBy...() before filtering.
Ok, so this is what my Fireabse database looks like:
Now I need to update the "about" node for every user. Without the user node, this is what I would do:
val mAllUserDatabase : DatabaseReference = FirebaseDatabase.getInstance().reference.child("Users"))
val childUpdates = HashMap<String, Any>()
childUpdates["/about"] = "new value"
mAllUserDatabase.updateChildren(childUpdates)
The problem is, I need to define the node of the user (don't I?). But since the user node all have a different name, I would need something like "any- node" or "all nodes". Something like
childUpdates["/any/about"] = "new value"
or getChildren()of the snapshots.
What would be the best way to solve this? Do I have to use addListenerForSingleValueEvent to read the names of all nodes and then use the names on mAllUserDatabase with .updateChildren(childUpdates)? That cant be the best way to do this.
To update your about property within all user objects, please use the following lines of code:
val rootRef = FirebaseDatabase.getInstance().reference
val usersRef = rootRef.child("Users")
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (ds in dataSnapshot.children) {
val childUpdates = HashMap<String, Any>()
childUpdates["about"] = "yourNewAboutValue"
ds.ref.updateChildren(childUpdates)
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
}
}
usersRef.addListenerForSingleValueEvent(valueEventListener)
To write a value to a node in the Firebase Realtime Database you need to know the exact path to that node. Firebase does not have the concept of SQL's update queries.
So in your case you'll need to first read the nodes you want to update, then loop over them, and then update them either one by one or with one big multi-location update statement.