I am having trouble retrieving a List from the Firebase. I have no trouble storing it, but as soon as I try to cast dataSnapshot.getValue() to ArrayList my app crashes, givi
You need to create a GenericTypeIndicator object to pass as DataSnapshot.getValue()
parameter.
Code:
GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {};
List<String> yourStringArray = dataSnapshot.getValue(t);
Your Model
public class TaskDes {
private boolean done;
private String taskDescription;
private String taskTitle;
public TaskDes() {
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
public String getTaskDescription() {
return taskDescription;
}
public void setTaskDescription(String taskDescription) {
this.taskDescription = taskDescription;
}
public String getTaskTitle() {
return taskTitle;
}
public void setTaskTitle(String taskTitle) {
this.taskTitle = taskTitle;
}
}
You need to create a GenericTypeIndicator object to pass as DataSnapshot.getValue()
parameter.
In Activity
private static final String TAG=MainActivity.class.getSimpleName();
private FirebaseDatabase database;
private DatabaseReference myRef=null;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
database=FirebaseDatabase.getInstance();
myRef=database.getReference("ADD_YOUR_REFERECE");
myRef.addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
/* This method is called once with the initial value and again whenever data at this location is updated.*/
long value=dataSnapshot.getChildrenCount();
Log.d(TAG,"no of children: "+value);
GenericTypeIndicator<List<TaskDes>> genericTypeIndicator =new GenericTypeIndicator<List<TaskDes>>(){};
List<TaskDes> taskDesList=dataSnapshot.getValue(genericTypeIndicator);
for(int i=0;i<taskDesList.size();i++){
Toast.makeText(MainActivity.this,"TaskTitle = "+taskDesList.get(i).getTaskTitle(),Toast.LENGTH_LONG).show();
}
}
@Override
public void onCancelled(DatabaseError error){
// Failed to read value
Log.w(TAG,"Failed to read value.",error.toException());
}
});
}
Make another item that contains a list for your item: This is your item:
class TaskDes { // definition
boolean done
String taskDescription
String taskTitle
}
This is the list item
class TaskDesList { // definition
private ArreyList<TaskDes> yourlist
}
public TaskDesList(){
}
public ArrayList<TaskDes> getYourlist() {
return yourlist;
}
and when calling an EventListener
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
yourlist.clear();
taskDesList=dataSnapshot.getValue(TaskDesList.class);
if (taskDesList!=null) {
yourlist= taskDesList.getYourlist();
}
}
and now "yourlist" is a list that contains all of your "TaskDes" items
A bit late, but in case any one else needs this.
IF the list is inside another object.
The object
public class Question {
public Date date;
public String questionNumber;
public String questionText;
public QuestionType questionType;
public String multipleSelection1;
public String multipleSelection2;
public String multipleSelection3;
public Question() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
}
Then to get your array of question objects
GenericTypeIndicator<List<Question>> t = new GenericTypeIndicator<List<Question>>() {};
List<Question> questionList = dataSnapshot.getValue(t);
Apparently, the GenericTypeIndicator doesn't work for all List objects particularly when the object contains none primitive types like maps. So, if it didn't work for your use case as it didn't for me, try this alternate solution:
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<TaskDes> tDlist = new ArrayList<>();
for (DataSnapshot d: dataSnapshot.getChildren()){
TaskDes tD = d.getValue(TaskDes.class);
tDlist.add(tD);
}
notifyDataSetChanged();
}
As mentioned in the previous answers make sure your class( like TaskDes in this case) has a public constructor which is empty so the getValue method can deserialize correctly to your java class.