我以前发过帖子,但不知道问题的帖子标准,所以我用代码重新格式化了我的问题。
我正在开发一个应用程序,它使用谷歌Map带你去当地旅游,并跟踪你去过哪些地标。
我已经设法写入数据库(如图所示),但每次尝试从数据库中读取时,它都声称 ulandmarks
为null,我正在尝试调用 .toString()
在空对象引用上。
这里我有一个集合(“users”)、一个文档(uid)和一个字段(“userlandmarks”),其中包含一个自定义landmark对象的数组。
我只想获取当前用户的userlandmarks列表,并将它们加载到本地列表中,我可以使用该列表填充googleMap,但我只能检索 Map<String,Object>
.
以下是我尝试过的和我的里程碑式课程:
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;
}
}
请帮忙。
2条答案
按热度按时间7xllpg7q1#
出现以下错误:
对空对象引用调用.tostring()
因为你想得到一个
landmarks
不存在的列表。数据库中的列表称为userLandmarks
而不是landmarks
. 要解决这个问题,您应该更改类中字段的名称以匹配数据库中的字段。我还写了一篇你可能感兴趣的文章:
如何将cloudfirestore中的对象数组Map到对象列表?
dgiusagp2#
热释光;dr:您试图在一个字段上使用toobject函数,而它打算用于整个文档
据我所知,在firebase sdk中,所有对象都保存为一个Map,当读取对象时,sdk会将Map取回并转换回一个新对象,请考虑下一个示例:
在写入任何firebase工具(firestore\realtime数据库)时,会将对象转换为一个Map,其中“field1”和“field2”将成为键,上传时它们的值将成为相应的值。
firebase为我们提供了一个工具,可以使用“toobject”函数将文档转换为对象(如果满足某些条件,请参见下文),如果我理解正确,您尝试使用特定字段(而不是整个文档)执行此操作,我想您会发现“ulandmarks”字段数组中的每个单元格都是以Map的形式出现的,如果是这样的话,我建议您尝试将此字段作为Map数组来读取,并从每个Map中获取数据来创建对象。
使用“toobject”函数的条件:类必须有一个空构造函数,每个数据成员都有一个setter。
我非常推荐在youtube或他的网站上看到firebase上的“流中编码”教程。祝你好运!