Issue
public class MainActivity extends AppCompatActivity { private PieChart pieChart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* barChart=findViewById(R.id.bargraph);
retrieveData();*/
pieChart=findViewById(R.id.pieChart);
loadPieChartData();
}
private void loadPieChartData(){
ArrayList<PieEntry> entries = new ArrayList<>();
entries.add(new PieEntry(0.2f,""));
entries.add(new PieEntry(0.10f,""));
entries.add(new PieEntry(7f,""));
entries.add(new PieEntry(10f,""));
entries.add(new PieEntry(8f,""));
Solution
To get data from Firestore and translate it into an array of PieEntry
objects you can do something like this (where you can call getData()
in onCreate
instead of your loadPieChartData()
to start getting the data, and then when it is retrieved it calls showPieChart
with the retrieved array from inside the onComplete
callback.
You should also have a look at the Firestore documentation, which has several examples of how to retrieve data.
void getData() {
db.collection("Categories").get().addOnCompleteListener(
new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
ArrayList<PieEntry> entries = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
Map<String,Object> data = document.getData();
String cat = (String)data.get("name");
Long amount = (Long)data.get("goal");
if( cat != null && amount != null ) {
entries.add(new PieEntry(amount.floatValue(), cat));
}
else {
Log.d(TAG, "Got bad data for " + document.getId() + " => " + document.getData());
}
}
// Once you fill the array, pass it to something to
// apply to the chart
showPieChart(entries);
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
}
);
}
void showPieChart(ArrayList<PieEntry> entries) {
// same code you currently have in "loadPieChartData", except that it
// takes "entries" as an input instead of hard-coding the values
}
Note
If the value of "goal" can be an integer type in some documents and a float in others, you will need a more robust way of reading it from the map. Something like the following would work (although just making sure your document uses consistent data types may be best):
Float readFloat(Object obj) {
if( obj instanceof Integer ) {
return ((Integer)obj).floatValue();
}
else if( obj instanceof Long) {
return ((Long)obj).floatValue();
}
else if (obj instanceof Float) {
return (Float)obj;
}
else if (obj instanceof Double) {
return ((Double)obj).floatValue();
}
return null;
}
and use it as:
Float val = readFloat(data.get("goal"));
Answered By - Tyler V
Answer Checked By - David Marino (JavaFixing Volunteer)