How to Retrieve a List object from the firebase in android

后端 未结 5 1942
无人共我
无人共我 2020-11-30 03:13

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

相关标签:
5条回答
  • 2020-11-30 03:45

    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);
    
    0 讨论(0)
  • 2020-11-30 03:49

    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());
           }
        });
     }
    
    0 讨论(0)
  • 2020-11-30 03:54

    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

    0 讨论(0)
  • 2020-11-30 03:54

    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);
    
    0 讨论(0)
  • 2020-11-30 04:06

    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.

    0 讨论(0)
提交回复
热议问题