I'm trying to display data from Firestore and add it to a PieChart.
I can't figure out why I can't access my data
This is how data are stored in Firestore:
This is how I try to access it:
private val mFirestore = FirebaseFirestore.getInstance()
var chartdata: ArrayList<Measurements> = ArrayList()
private var chart: ScatterChart? = null
fun getCurrentUserID(): String {
val currentUser = FirebaseAuth.getInstance().currentUser
var currentUserID = ""
if (currentUser != null) {
currentUserID = currentUser.uid
}
return currentUserID
}
mFirestore.collection(Constants.MEASUREMENTS)
.whereEqualTo(Constants.USER_ID, getCurrentUserID())
.get()
.addOnSuccessListener { queryDocumentSnapshots ->
val userdata : ArrayList<Measurements> = ArrayList()
val weekdata = ArrayList<Measurements>()
if (!queryDocumentSnapshots.isEmpty) {
for (journals in queryDocumentSnapshots) {
val displayData: Measurements = journals.toObject(Measurements::class.java)
userdata.add(displayData)
Log.e("Data for chart", journals.toString())
}
And I get this error:
enter image description here
The data is being fetched precisely that's why you can see all the document names in the logcat but as you are logging DocumentSnapshot object, that's why you are seeing the data in unusual format. Try logging displayData variables like:
Log.d("Data for chart", displayData.activity) // Use Log.d instead of Log.e
or userdata as an array and it will work as desired.
Related
So I want to retrieve a particular Document from a Collection in Firestore and assign the document to a variable so that i can use it in other activity.
Collection contains Users as documents.
FirebaseFirestore.getInstance().collection(Users).document(getCurrentUserID()).get() ....
Model class: USER
fun getCurrentUserID(): String {
var currentUser = FirebaseAuth.getInstance().currentUser
var currentUserID = ""
if (currentUser != null) {
currentUserID = currentUser.uid
}
return currentUserID
}
You can get your user with using code below, then you can do whatever you want with it.
FirebaseFirestore.getInstance()
.collection("Users")
.document(getCurrentUserID())
.get()
.addOnSuccessListener { document ->
val user = document.toObject(USER::class.java)!!
// Now we stored information to user variable.
// You can use it by simply calling user.name etc.
// If you want to use it out of this block,
// you need to send it there, example to a function
deleteUserDetails(user)
}
.addOnFailureListener { e ->
Log.e(
this.javaClass.simpleName,
"Error while getting user details.",
e
)
}
fun deleteUserDetails(user: USER) {
// Now you can use it here too.
// Example set a textView with user.name or etc.
textView.text = user.name
}
I would like to ask for help on how to retrieve data from Firestore for nested Array of Maps called "cities" into MutableList , which I then want to insert into recycler view, where the data from the “regions” are for the header and data “cities” for the regular list items.
Data for regions: MutableList , when I follow the procedure https://medium.com/firebase-tips-tricks/how-to-map-an-array-of-objects-from-cloud-firestore-to-a-list -of-objects-122e579eae10 by Alex Mamo, got fine, but data for: cities: MutableList , according same approach, is null (unable to retrive).
Can you please advise how to get data for “cities”?
P.s. somewhere I read the recommendation to iterate over "cities", but I have no idea how, please go straight for an example (ideally in Kontlin).
Code:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
…..
regionsRef.get().addOnCompleteListener { document ->
if (document.isSuccessful()) {
val documentSnapshot = document.result
// Retrieve array of maps for „regions“
val regions = documentSnapshot.toObject(RegionDocument::class.java)?.regions
// Retrieve array of maps for „cities“
val cities = documentSnapshot.toObject(CityDocument::class.java)?.cities
…
}
}
Data classes for object City:
data class City(
val cityNumber: Long? = null,
val cityName: String? = "" )
data class CityDocument(
var cities: MutableList<City>? = null)
Firestore structure:
To be able to get the data that corresponds to your document structure, you need three classes:
class Document {
var regions: MutableList<Region>? = null
}
class Region {
var cities: MutableList<City>? = null
var regionName: String? = null
var regionNumber: Long? = null
}
class City {
var cityName: String? = null
var cityNumber: Long? = null
}
And below you can find a solution for reading all cities:
val db = FirebaseFirestore.getInstance()
val docIdRef = db.collection("collName").document("docId")
docIdRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val document = task.result
if (document != null) {
val doc = document.toObject(Document::class.java)
if (doc != null) {
val regions = doc.regions
if (regions != null) {
for (region in regions) {
val cities = region.cities
//Do what you need to to do with your List<City>.
}
}
}
}
} else {
Log.d("TAG", task.exception!!.message!!) //Never ignore potential errors!
}
}
Now, simply replace collName and docId with the one you have in your database.
I'm trying to model a database schema for Firestore. How can I create this database model?
This is my recipe data class
data class Foods(
var foodId:String?,
var foodName:String,
var foodCategory:String,
var foodCalory:Int,
var foodIngredients:String,
var foodRecipe:String,
var foodCookingTime:Int,
var foodImg:String?)
My Users Id getting this
val user : FirebaseUser? = auth?.currentUser
val userID: String = user?.uid.toString()
As I see in your screenshot, your document (vp0q ...) holds an array of Foods objects. If you want to be able to map that document to an object of a particular class, you should consider using the following class declarations:
data class User (recipe: Array<Foods>)
Now, to read that document, you should use the following reference:
val uid = FirebaseAuth.getInstance().currentUser?.uid
val rootRef = FirebaseFirestore.getInstance()
val usersRef = rootRef.collection("users")
usersRef.document(uid).get()
.addOnSuccessListener { document ->
if (document != null) {
val recipe = document.toObject<Foods>().recipe
//Do what you need to do with your recipe array
} else {
Log.d(TAG, "No such document")
}
}
.addOnFailureListener { exception ->
Log.d(TAG, "get failed with ", exception)
}
I stored all the users information in the firestore with their UID as a document. Now i create a Node as Friends in realtimeDatabase with the UID as child. Now i want to retrieve only the users whose UID is present in Friends node but the users are not showing in the recyclerView or i don't know the right way.
Firestore where all the user's info saved
And this is how were node Friends created on an operation.
FirebaseDatabase.getInstance().reference
.child("Friends")
.child(currentUserID)
.child(profileId)
.setValue("Friend")
.addOnSuccessListener{
FirebaseDatabase.getInstance().reference
.child("Friends")
.child(profileId)
.child(currentUserID)
.setValue("Friend")}
And this is how i am trying to retrieve them in a recyclerView in a fragment according to Realtime-Database
private fun retrieveFriends()
{
val usersRef = FirebaseDatabase.getInstance().reference.child("Friends")
usersRef.addValueEventListener(object : ValueEventListener
{
override fun onDataChange(dataSnapshot: DataSnapshot)
{
mFriend?.clear()
for (snapshot in dataSnapshot.children)
{
val friend = snapshot.getValue(User::class.java)
if (friend != null)
{
mFriend?.add(friend)
}
friendAdapter?.notifyDataSetChanged()
}
}
})
}
In the userAdapter, setting up the values like this
private fun friendInfo(fullName: TextView, about: TextView, location: TextView, profileImage: CircleImageView) {
val pref = mContext.getSharedPreferences("PREF", Context.MODE_PRIVATE)
if (pref != null) {
this.profileId = pref.getString("profileId", "none").toString()
}
val userRef = FirebaseFirestore.getInstance().collection("Users").document(profileId)
userRef.get()
.addOnSuccessListener { documentSnapshot ->
if (documentSnapshot != null && documentSnapshot.exists()) {
val user = documentSnapshot.toObject(User::class.java)
Picasso.get().load(user!!.getImage()).placeholder(R.drawable.default_pro_pic).into(profileImage)
fullName.text = user.getFullName()
about.text = user.getAbout()
location.text = user.getLocation()
}
}
}
You have to do changes while retrieving users from, where you are retrieve users with there uid but if you think that all the information of the user will also display then it will never happen because you have just saved the uid as value in firebase try this
private fun retrieveFriends()
{
val usersRef = FirebaseDatabase.getInstance().reference.child("Friends")
usersRef.addValueEventListener(object : ValueEventListener
{
override fun onDataChange(dataSnapshot: DataSnapshot)
{
mFriend?.clear()
val friend = snapshot.getValue(User::class.java)
for each{
val friendID = it.key
mFriend?.add(User(userId = friendID)
}
friendAdapter?.notifyDataSetChanged()
}
})
}
Now you just make another constructor in your User model class with a single userId parameters
constructor(userId : String)
{
this.userId = userId
}
i need to get data from object (named "0") in a document in firestore, is that possible ?
this is my code now:
val db = FirebaseFirestore.getInstance()
val docRef = db.collection("accessories")
.document("brand0")
docRef.get().addOnCompleteListener(OnCompleteListener<DocumentSnapshot> { task ->
if (task.isSuccessful) {
val document = task.result
val group = document.get("0") as ArrayList<String>
}
but casting Any to Arraylist is not possible, any other way to get these data ?
It looks like 0 is a an object type field. That means it'll be represented locally as a Map type object with strings as the keys for the properties it contains.
After some trials and errors this is what worked for me in the end, but I am not sure why. I am using kotlin in my current project.
fun getOwner(userId: String) {
val db = Firebase.firestore
val docRef = db.collection("users").document(userId)
docRef.get()
.addOnSuccessListener { document ->
if (document != null) {
Log.d(TAG, "DocumentSnapshot data: ${document.data}")
val data = document.data as Map<String, String>
showOwnerName.text = data["name"]
} else {
Log.d(TAG, "No such document")
}
}
.addOnFailureListener { exception ->
Log.d(TAG, "get failed with ", exception)
}
}
I am converting the data I am getting to a map and this is how I am able to access its values.