instanceof不适用于从Firebase实时数据库

时间:2018-01-28 09:36:17

标签: java android firebase arraylist firebase-realtime-database

我有以下三个班级:

class Parent{
  public String title;
  public Parent(){}
  public void setTitle(String title){
    this.title = title;
  }
  public String getTitle(){
    return this.title;
  }
}

儿童1

class Child1 extends Parent{
  public String c1title;
  public Child1(){}
  public void setC1title(String title){
    this.c1title = title;
  }
  public String getC1itle(){
    return this.c1title;
  }
}

儿童2

class Child2 extends Parent{
  public String c2title;
  public Child2(){}
  public void setC2title(String title){
    this.c2title = title;
  }
  public String getC2itle(){
    return this.c2title;
  }
}

我将子类的实例存储在ArrayList< Parent>中。列出并将ArrayList上传到RealtimeDatabase。我可以成功检索ArrayList,但是这段代码无法按照从Firebase检索到的ArrayList的方式工作,但适用于本地ArrayList:

for(Parent p : list){  //list is the ArrayList<Parent> obtained from Firebase
  if(p instanceof Child1){
    Log.d("Activity1", "1st child");
  }
  if(p instanceof Child2){
    Log.d("Activity1", "2nd child");
  }
  else{
  Log.d("Activity1", "No match found");
  }
}

我无法理解背后的原因。本地存储的ArrayList是否有一些关于存储对象的附加信息,这些信息在存储在Firebase中时会丢失?过滤掉子对象的理想解决方法是什么?

编辑:从Firebase检索ArrayList的代码

mDatabaseReference = FirebaseDatabase.getInstance().getReference("test");
        mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                GenericTypeIndicator<ArrayList<Parent>> t = new GenericTypeIndicator<ArrayList<Parent>>() {};
                ArrayList<Parent> yourStringArray = dataSnapshot.getValue(t);
                List<Parent> list = dataSnapshot.getValue(t);
                Log.d(TAG, "Successfully obtained the test list");
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

1 个答案:

答案 0 :(得分:0)

要从数据库中读取您正在使用的数据:

GenericTypeIndicator<ArrayList<Parent>> t = new GenericTypeIndicator<ArrayList<Parent>>() {};
ArrayList<Parent> yourStringArray = dataSnapshot.getValue(t);
List<Parent> list = dataSnapshot.getValue(t);

在此代码中,您告诉Firebase从快照中读取Parent实例,这正是它所做的。

如果您希望它读取您写入数据库的特定子项,则必须执行以下两项操作:

  1. 将有关类类型的信息写入数据库。
  2. 从数据库中读取时,向Firebase询问该特定类的实例。
  3. 所以在写作时,这可能是:

    if (object instanceof "Child1") {
      ref.child("type").set("Child");
    }...
    

    然后在回读时,您将读取数据,循环结果并根据type属性实例化正确的类:

    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot child: dataSnapshot.getChildren()) {
                String type = child.getChild("type").getValue(String.class);
                if ("Child1".equals(type)) {
                    Child1 child1 = child.getValue(Child1.class);
                }...
            }
        }
    

    我认为在单个API调用的整个孩子列表中没有任何方法可以做到这一点。