29

我无法从 Firebase 中检索列表。我存储它没有问题,但是一旦我尝试将 dataSnapshot.getValue() 转换为 ArrayList,我的应用程序就会崩溃,并给出一个异常:

HashMap 不能转换为 ArrayList

但是当我尝试将其转换为 HashMap 时,它也会崩溃,并给出异常:

ArrayList 不能转换为 hashmap

请需要帮助!这是产生问题的代码:

Fire.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<TaskDes> td = (ArrayList<TaskDes>) dataSnapshot.getValue()
        notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});

firebase 对象屏幕截图

我想将 Firebase 中的所有数据作为一个列表检索。TaskDes 类包含三个字段:

class TaskDes { // definition
    boolean done
    String taskDescription
    String taskTitle
}
4

5 回答 5

43

您需要创建一个 GenericTypeIndicator 对象作为DataSnapshot.getValue()参数传递。

代码:

GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {};

List<String> yourStringArray = dataSnapshot.getValue(t);
于 2016-03-14T04:46:33.340 回答
11

你的模型

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;
    }

}

您需要创建一个GenericTypeIndicatorDataSnapshot.getValue()对象作为参数传递。

活动中

 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());
       }
    });
 }
于 2017-01-06T10:41:48.897 回答
2

制作另一个包含您的项目列表的项目:这是您的项目:

class TaskDes { // definition
    boolean done
    String taskDescription
    String taskTitle
}

这是列表项

        class TaskDesList { // definition
              private  ArreyList<TaskDes> yourlist
            }

      public TaskDesList(){
         }

        public ArrayList<TaskDes> getYourlist() {
            return yourlist;
        }

并且在调用 EventListener 时

ref.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                yourlist.clear();
             taskDesList=dataSnapshot.getValue(TaskDesList.class);
                if (taskDesList!=null) {
                    yourlist= taskDesList.getYourlist();
                }
}

现在“yourlist”是一个包含所有“TaskDes”项目的列表

于 2017-07-17T15:02:52.423 回答
1

有点晚了,但以防万一其他人需要这个。

如果列表在另一个对象内。

物体

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)
    }
}

然后得到你的问题对象数组

GenericTypeIndicator<List<Question>> t = new GenericTypeIndicator<List<Question>>() {};
List<Question> questionList = dataSnapshot.getValue(t);
于 2017-03-24T10:24:40.797 回答
0

显然,GenericTypeIndicator 不适用于所有 List 对象,尤其是当对象不包含像地图这样的原始类型时。因此,如果它不适用于您的用例,因为它不适用于我,请尝试以下替代解决方案:

 @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();
 }

如前面的答案所述,确保您的类(如本例中的 TaskDes)有一个为空的公共构造函数,以便 getValue 方法可以正确反序列化为您的 java 类。

于 2019-03-08T15:00:02.420 回答