Java 如何在Android中从CloudFireStore检索自定义对象列表
我以前发过帖子,但不知道问题的帖子标准,所以我用代码重新格式化了我的问题 我正在开发一个应用程序,它使用谷歌地图带你进行本地旅游,并跟踪你访问过的地标 我已成功写入数据库(如图所示),但每次尝试从数据库读取时,它都会声称Java 如何在Android中从CloudFireStore检索自定义对象列表,java,android,firebase,google-maps,google-cloud-firestore,Java,Android,Firebase,Google Maps,Google Cloud Firestore,我以前发过帖子,但不知道问题的帖子标准,所以我用代码重新格式化了我的问题 我正在开发一个应用程序,它使用谷歌地图带你进行本地旅游,并跟踪你访问过的地标 我已成功写入数据库(如图所示),但每次尝试从数据库读取时,它都会声称ulandmarks为null,并且我试图对null对象引用调用.toString() 这里我有一个集合(“用户”)、一个文档(uID)和一个字段(“userLandmarks”),其中包含一个自定义LandMark对象数组 我只想获取当前用户的userLandmarks列表,
ulandmarks
为null,并且我试图对null对象引用调用.toString()
这里我有一个集合(“用户”)、一个文档(uID)和一个字段(“userLandmarks”),其中包含一个自定义LandMark对象数组
我只想获取当前用户的userLandmarks列表,并将它们加载到本地列表中,以便填充Google地图,但我只能检索Map
列表
以下是我尝试过的内容和我的Landmark课程:
public void readUserData(String userID){
userID = getUserID();
CollectionReference usersRef = db.collection("users");
DocumentReference usersIdRef = usersRef.document(userID);
usersIdRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if(document.exists()) {
//This here returns a map but I want a list of Landmarks
//List<Map<String, Object>> userLandmarks = (List<Map<String, Object>>) document.get("userLandmarks");
List<LandMark> ulandmarks = document.toObject(LandmarkDocument.class).landmarks;
Log.v("DatabaseRead", "Successfully read from the database: "+ulandmarks.toString());
}
}
}
});
}
//Separate LandmarkDocument Class
public class LandmarkDocument {
public List<LandMark> landmarks;
public LandmarkDocument(){}
}
public class LandMark {
//GLOBALS
private int mID;
private String mName;
private LatLng mLocation;
private double mLatitude;
private double mLongitude;
private String mDesc;
private int mImage;
private boolean isVisited;
//GLOBALS
public LandMark() {
}
public LandMark(int mID, String mName, double mLatitude, double mLongitude, String mDesc, int mImage, boolean isVisited) {
// ID and NAME
this.mID = mID;
this.mName = mName;
// LOCATION, LATITUDE, and LONGITUDE
this.mLocation = new LatLng(mLatitude, mLongitude);
this.mLatitude = mLatitude;
this.mLongitude = mLongitude;
// LANDMARK DESCRIPTION
this.mDesc = mDesc;
// LANDMARK IMAGE
this.mImage = mImage;
// BOOLEAN VISITED FLAG
this.isVisited = isVisited;
}
public String getName() {
return mName;
}
public void setName(String mName) {
this.mName = mName;
}
public LatLng getLocation() {
return mLocation;
}
public double getLatitude(){
return mLatitude;
}
public void setLatitude(double mLatitude){
this.mLatitude = mLatitude;
}
public double getLongitude(){
return mLongitude;
}
public void setLongitude(double mLongitude){
this.mLongitude = mLongitude;
}
public void setLocation(double mLatitude, double mLongitude) {
this.mLocation = new LatLng(mLatitude, mLongitude);
}
public String getDesc() {
return mDesc;
}
public void setDesc(String mDesc) {
this.mDesc = mDesc;
}
public int getID() {
return mID;
}
public void setID(int mID) {
this.mID = mID;
}
public int getImage(){
return mImage;
}
public void setImage(int mImage){
this.mImage = mImage;
}
public boolean isVisited(){
return isVisited;
}
public void setVisited(boolean isVisited){
this.isVisited = isVisited;
}
}
public void readUserData(字符串userID){
userID=getUserID();
CollectionReference usersRef=db.collection(“用户”);
DocumentReference usersIdRef=usersRef.document(userID);
usersIdRef.get().addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
DocumentSnapshot document=task.getResult();
if(document.exists()){
//这里返回一张地图,但我想要一个地标列表
//List userLandmarks=(List)document.get(“userLandmarks”);
List ulandmarks=document.toObject(LandmarkDocument.class).landmarks;
Log.v(“DatabaseRead”,“从数据库成功读取:“+ulandmarks.toString()”);
}
}
}
});
}
//单独的LandmarkDocument类
公共类地标文档{
公开列出地标;
公共LandmarkDocument(){}
}
公共类地标{
//全球的
私人int mID;
私有字符串mName;
私人停车场;
私人双重国籍;
私人双重身份;
私有字符串mDesc;
私人图像;
私人诊所;
//全球的
公共地标(){
}
公共地标(整数mID、字符串mName、双精度、双精度、字符串mDesc、整数mImage、布尔值isVisited){
//身份证和姓名
this.mID=mID;
this.mName=mName;
//位置、纬度和经度
this.mLocation=新车床(高度、长度);
this.mLatitude=mLatitude;
this.mLongitude=mLongitude;
//地标描述
this.mDesc=mDesc;
//地标图像
this.mImage=mImage;
//布尔访问标志
this.isvisted=isvisted;
}
公共字符串getName(){
返回mName;
}
public void setName(字符串mName){
this.mName=mName;
}
公共位置(){
返回位置;
}
公共双纬度(){
返回时间;
}
公共空间设置纬度(双纬度){
this.mLatitude=mLatitude;
}
公共双getLongitude(){
返回长度;
}
公共空间设置经度(双倍长度){
this.mLongitude=mLongitude;
}
公共空隙设置位置(双倍高度、双倍长度){
this.mLocation=新车床(高度、长度);
}
公共字符串getDesc(){
返回mDesc;
}
公共void setDesc(字符串mDesc){
this.mDesc=mDesc;
}
公共int getID(){
中途返回;
}
公共无效集合ID(int mID){
this.mID=mID;
}
public int getImage(){
返回图像;
}
公共void setImage(int-mImage){
this.mImage=mImage;
}
公共布尔值(){
回访;
}
已访问的公共void集(已访问的布尔值){
this.isvisted=isvisted;
}
}
请帮忙
TL;DR:您试图在一个字段上使用toObject函数,当它
用于整个文档
据我所知,在FielBaseSDK中,所有对象都保存为一个映射,当读取对象时,SDK将映射并将其转换为新对象,考虑下一个例子:
public class MyObject{
private String field1;
private String field2;
}
写入任何firebase工具(firestore\realtime database)后,将对象转换为地图,其中“field1”和“field2”将成为键,上传时它们的值将成为相应的值
firebase为我们提供了一个工具,可以使用“toObject”功能将文档转换为对象(如果满足某些条件,请参见下文),如果我理解正确,您正试图使用特定字段(而不是整个文档)执行此操作
我认为您会发现“ulandmarks”字段数组中的每个单元格都是以贴图的形式出现的,如果是这样,我建议您尝试将此字段作为贴图数组来读取,并从每个贴图中获取数据以创建对象
使用“toObject”函数的条件:类必须有一个空构造函数,每个数据成员必须有一个setter
我非常推荐在youtube或他的网站上看到firebase上的“流中编码”教程。
祝你好运 您将收到以下错误: 对空对象引用调用.toString() 因为您试图获取一个不存在的
地标列表。数据库中的列表称为userLandmarks
和非landmarks
。要解决此问题,您应该更改类中字段的名称以匹配数据库中的字段
public class LandmarkDocument {
public List<LandMark> userLandmarks;
public LandmarkDocument(){}
//...
}
公共类LandmarkDocument{
公共列表用户地标;
公共LandmarkDocument(){}
//...
}
我还写了一篇你可能感兴趣的文章: