Reputation: 1386
I have a Fierbase Realtime Database with the following structure:
data
0
category : "Some category"
1
category : "Some category"
2
category : "Another category"
It is a long list with items of different categories (they have more fields, buy they are irrelevant for this I think). I am doing a query to get all the items of a given category:
firebaseDatabase.child("data")
.orderByChild("category")
.equalTo(category.name)
And I am processing the snapshot in the following way:
snapshot.getValue<List<FirebaseEntry>>()!!.filterNotNull().map { it.toEntry() }
This code seemed to work fine (I could get all entries of some of the categories), and while I tested different categories, I got an Exception only for some of them:
com.google.firebase.database.DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap
I don't understand why it works for some categories and fails for other ones, since the data structure is the same for all. I tried then to parse it as a HashMap:
snapshot.getValue<HashMap<String, FirebaseEntry>>()!!.map { it.value.toEntry() }.sortedBy { it.id }
This apparently fixed it for those categories, but I got an exception in those that worked previously:
com.google.firebase.database.DatabaseException: Expected a Map while deserializing, but got a class java.util.ArrayList
Is there a reason for the result to come in a different format when the data in the database is similar? The full list is about 300 items, and they are in category order (all items of one category first, then another category and so on), I don't think that is the reason but I am lost right now and I can't see what is wrong.
Upvotes: 3
Views: 770
Reputation: 598797
Firebase SDKs coerce the data coming back from the server into an array/List
if it meets certain conditions. As Kato says in Best Practices: Arrays in Firebase:
In particular, if all of the keys are integers, and more than half of the keys between 0 and the maximum key in the object have non-empty values, then Firebase will render it as an array.
When you don't have a condition, your data matches these conditions and the result is presented as a List
. But when you have a condition on the query, the conditions might not be met and the result becomes a Map
.
There is nothing you can do about this conversion, so your options are limited to:
getValue()
without a type and then perform a dynamic type-check to see what you got back.List
ever, by prefixing the numeric value with a fixed string. E.g. key0
, key1
, etc.Upvotes: 3