【问题标题】:How to Retrieve a List object from the firebase in android如何从android中的firebase中检索List对象
【发布时间】:2015-08-24 23:45:50
【问题描述】:

我在从 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 中的所有数据检索为一个列表。 TaskDes 类包含三个字段:

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

【问题讨论】:

标签: android arraylist firebase firebase-realtime-database


【解决方案1】:

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

代码:

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

List<String> yourStringArray = dataSnapshot.getValue(t);

【讨论】:

  • 如果列表在另一个对象中怎么办?
  • @GregEnnis 如果列表在另一个对象中,你有没有想过如何解决它?
  • @GregEnnis 我找到了方法。 GenericTypeIndicator&lt;MyModel&gt; t = new GenericTypeIndicator&lt;MyModel&gt;() {}; 就这样。在我的MyModel 中,我有一个List 以及其他字段。
  • 老兄,你救了我的命
【解决方案2】:

你的模型

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

}

您需要创建一个GenericTypeIndicator 对象以作为DataSnapshot.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());
       }
    });
 }

【讨论】:

  • 感谢它帮助很大
【解决方案3】:

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

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”项目的列表

【讨论】:

    【解决方案4】:

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

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

    对象

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

    【讨论】:

      【解决方案5】:

      显然,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 类。

      【讨论】:

        猜你喜欢
        • 2017-01-21
        • 2014-06-02
        • 1970-01-01
        • 2016-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多