如何在android中从CloudFireStore检索自定义对象列表

1yjd4xko  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(344)

我以前发过帖子,但不知道问题的帖子标准,所以我用代码重新格式化了我的问题。
我正在开发一个应用程序,它使用谷歌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;
    }

}

请帮忙。

7xllpg7q

7xllpg7q1#

出现以下错误:
对空对象引用调用.tostring()
因为你想得到一个 landmarks 不存在的列表。数据库中的列表称为 userLandmarks 而不是 landmarks . 要解决这个问题,您应该更改类中字段的名称以匹配数据库中的字段。

public class LandmarkDocument {
    public List<LandMark> userLandmarks;

    public LandmarkDocument(){}

   //...
}

我还写了一篇你可能感兴趣的文章:
如何将cloudfirestore中的对象数组Map到对象列表?

dgiusagp

dgiusagp2#

热释光;dr:您试图在一个字段上使用toobject函数,而它打算用于整个文档
据我所知,在firebase sdk中,所有对象都保存为一个Map,当读取对象时,sdk会将Map取回并转换回一个新对象,请考虑下一个示例:

public class MyObject{
private String field1;
private String field2;
}

在写入任何firebase工具(firestore\realtime数据库)时,会将对象转换为一个Map,其中“field1”和“field2”将成为键,上传时它们的值将成为相应的值。
firebase为我们提供了一个工具,可以使用“toobject”函数将文档转换为对象(如果满足某些条件,请参见下文),如果我理解正确,您尝试使用特定字段(而不是整个文档)执行此操作,我想您会发现“ulandmarks”字段数组中的每个单元格都是以Map的形式出现的,如果是这样的话,我建议您尝试将此字段作为Map数组来读取,并从每个Map中获取数据来创建对象。
使用“toobject”函数的条件:类必须有一个空构造函数,每个数据成员都有一个setter。
我非常推荐在youtube或他的网站上看到firebase上的“流中编码”教程。祝你好运!

相关问题