如何从android中的firebase中检索List对象
Posted
技术标签:
【中文标题】如何从android中的firebase中检索List对象【英文标题】:How to Retrieve a List object from the firebase in android 【发布时间】: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
【问题讨论】:
很遗憾,这里没有足够的代码来帮助您解决问题。积极的一面:Firebase 的 androidChat 示例应用可以满足您的所有需求,仅此而已。在这里看看:github.com/firebase/AndroidChat/tree/master/app/src/main/java/…。我最近在 Firebase Google Group 上解释了它的内部结构:groups.google.com/d/msg/firebase-talk/OCoQPvpgl1U/Nli_OywG7LYJ 谢谢,我会试一试,另一件事我想问一下我是否将 hashmapTask
类建模。看看这个例子。你的Task
应该看起来像github.com/firebase/AndroidChat/blob/master/app/src/main/java/…
【参考方案1】:
您需要创建一个 GenericTypeIndicator 对象以作为DataSnapshot.getValue()
参数传递。
代码:
GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() ;
List<String> yourStringArray = dataSnapshot.getValue(t);
【讨论】:
如果列表在另一个对象中怎么办? @GregEnnis 如果列表在另一个对象中,你有没有想过如何解决它? @GregEnnis 我找到了方法。GenericTypeIndicator<MyModel> t = new GenericTypeIndicator<MyModel>() ;
就这样。在我的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 类。
【讨论】:
以上是关于如何从android中的firebase中检索List对象的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 android 中的用户位置从 Firebase 数据库中检索数据?
如何从firebase检索多个数据到android中的列表视图?
发送数据时,从 Android 应用中的 Firebase 检索 ServerValue.Timestamp
我如何从firebase检索数据到android listview顶部[重复]