'How to read data from nested array in Firestore
I have the below structure in my Firestore and I want to read data and store it in ArrayList like I have "amountArrayList" which will read data from the "transactions" field in Firestore, I want to read all the "amount" fields from "transactions" field and make array list of it so that I can show it in list manner.
My code
Map<String, Object> map = document.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("transactions")) {
System.out.println(entry.getValue().toString());
}
}
Output
[{transactionType=Credit, amount=3000, dateToStr=17/12/2021, timeToStr=08:06:10, description=}, {transactionType=Credit, amount=2000, dateToStr=17/12/2021, timeToStr=08:06:50, description=}]
Solution 1:[1]
Since transactions
is an array field, the value you get from entry.getValue()
is a List
of objects. Since each of these objects in the JSON has properties, they each will be a Map<String, Object>
again in the Java code.
A simple way to print the amounts would be something like:
List transactions = document.get("transactions");
for (Object transaction: transactions) {
Map values = (Map)transaction;
System.out.println(values.get("amount")
}
Solution 2:[2]
While Frank van Puffelen's answer will work perfectly fine, there is a solution in which you can directly map the "transactions" array into a list of custom objects. Assuming that you have a class declaration that looks like this:
class User {
public String balance, email, firstname, lastname, password, username;
public List<Transaction> transactions;
public User(String balance, String email, String firstname, String lastname, String password, String username, List<Transaction> transactions) {
this.balance = balance;
this.email = email;
this.firstname = firstname;
this.lastname = lastname;
this.password = password;
this.username = username;
this.transactions = transactions;
}
}
And one that looks like this:
class Transaction {
public String amount, dateToStr, description, timeToStr, transactionType;
public Transaction(String amount, String dateToStr, String description, String timeToStr, String transactionType) {
this.amount = amount;
this.dateToStr = dateToStr;
this.description = description;
this.timeToStr = timeToStr;
this.transactionType = transactionType;
}
}
To get the list, it will be as simple as:
docRef.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
List<Transaction> transactions = document.toObject(User.class).transactions;
List<String> amountArrayList = new ArrayList<>();
for(Transaction transaction : transactions) {
String amount = transaction.amount;
amountArrayList.add(amount);
}
// Do what you need to do with your amountArrayList
}
}
});
You can read more info in the following article:
Solution 3:[3]
I found the best way to map the data from/to hashmap to send/retrieve it from FirebaseFirestore
First, you need to create an extension class to handle the mapping
fun <T> T.serializeToMap(): Map<String, Any> {
return convert()
}
inline fun <reified T> Map<String, Any>.toDataClass(): T = convert()
inline fun <A, reified B> A.convert(): B =
Gson().fromJson(Gson().toJson(this), object : TypeToken<B>() {}.type)
Don't forget to add Gson
implementation 'com.google.code.gson:gson:2.9.0'
Then, you can use these functions for mapping the result from firebase
if (task.isSuccessful) {
val list: MutableList<YourObject> = ArrayList()
for (document in task.result) {
list.add(document.data.toDataClass())
}
// do whatever you want with the list :)
} else {
// handle the error
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Frank van Puffelen |
Solution 2 | |
Solution 3 | 3ameration |