Bloody beginner in Kotlin/Android here and trying his best.
I am trying to push a list of data objects into Firestore and managed to pull that off with the following function:
fun createData(collectionName:String){
//Create Data here
val docData: MutableMap<String, Any> = HashMap()
docData["data"] = Arrays.asList(
JournalEntry("Title 1", 0, 0),
JournalEntry("Title 2", 0, 1),
JournalEntry("Title 3", 0, 0)
)
db.collection(collectionName)
.add(docData)
.addOnSuccessListener { documentReference ->
Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}")
}
.addOnFailureListener { e ->
Log.w(TAG, "Error adding document", e)
}
}
This creates the following in Firestore:
Now I try to receive my data using a function provided by the docs. However, I am stuck on turning the data back into a list containing my data classes that I just created. I tried a few things and I didn't manage to resolve the issue reading the docs.
fun readFromDB(collectionName: String){
db.collection(collectionName)
.get()
.addOnSuccessListener { result ->
for (document in result) {
Log.d(TAG, "${document.id} => ${document.data}")
var values = ArrayList(document.data.values).toList()
//--------------------------------------------------
//I have no clue what to do starting from this point.
//--------------------------------------------------
println(values)
}
}
.addOnFailureListener { exception ->
Log.w(TAG, "Error getting documents.", exception)
}
}
Printing out the result which is a hashMap gives me:
[[{moodLevel=0, imageId=0, text=Title 1}, {moodLevel=1, imageId=0, text=Title 2}, {moodLevel=0, imageId=0, text=Title 3}]]
Question: How can I turn this result into a list of objects again?
Tried a few things but nothing worked. Also read through a few threads here and didn't find an answer that could apply to my use case. Any help would be appreciated. Sorry for this question if it's really obvious in its solution.
CodePudding user response:
You can convert your list to a HashMap as follows:
val map = list.associateBy({it.title}, {it})
So you would have a map with a title as your key and the content of the object. (Since the titles can be repeated, I recommend assigning an ID so that you associate the object with that ID)
Then you just upload your map by doing:
db.collection(/*your collection*/).document(/*your document*/).set(map, SetOptions.merge() /*Optional if you don't want all fields with the same ID to be overwritten */)
Then to get it:
db.collection().document().get().addOnSuccessfullyListener{
val list = it.toObjects(JournalEntry::class.java)
}
Or if you don't want to modify what you already have, when you get the data, take it out of the array, since you would be doing nested lists, just leave:
val values = document.data.values.toList()
And I recommend installing the Gson library to convert the objects to Json and vice versa, and you just get it:
val myEntriesList = values.map { Gson().fromJson(it.toString, JournalEntry::class.java) }
CodePudding user response:
Unfortunately, Firestore doesn't provide a toList()
method inside the DocumentSnapshot class. However, there is a really simple solution that can solve this issue. So to get the content of the "data" array and convert it into a list of JournalEntry
objects, then you should simply create a new class that contains that specific list like this:
data class JournalEntryDoc (
var journalEntryList: MutableList<JournalEntry>? = null
)
Now to read the data, you can simply use:
val journalEntryList = document.toObject(JournalEntry.class).journalEntryList
I have also written an article on this topic called: