【问题标题】:Failure to read a custom object from Firestore--why?无法从 Firestore 读取自定义对象 - 为什么?
【发布时间】:2019-11-16 06:45:27
【问题描述】:

我收到此错误消息

java.lang.RuntimeException:无法反序列化对象。无法将 java.util.ArrayList 类型的值转换为字符串(在字段 'allNames' 中找到)

当我尝试将文档从 Firestore 读取到自定义对象 DBStructure.class 中时。

这是我用来检索数据的代码:


    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private DocumentReference DBStructureDocRef = db.document(DB_STRUCTURE_PATH);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoom = new Room();
        mDBStructure = new DBStructure();

        readData();
        HandleSpinnerSelection("", -1);
    }

    private void readData() {
        DBStructureDocRef.get()
                .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                    @Override
                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                        if (documentSnapshot.exists()) {
                            **mDBStructure = documentSnapshot.toObject(DBStructure.class)**;
                        }
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(MainActivity.this, "Error!", Toast.LENGTH_SHORT).show();
                        Log.d(TAG, e.toString());
                    }
                });
    }

这是 DBStructure.class。

    public class DBStructure {

    List<String> allTypes = new ArrayList<>();
    List<String> allNames = new ArrayList<>();
    List<String> allSurfaces = new ArrayList<>();
    Map<String, Map<String, Unit>> hospitalLayout = new HashMap<>();

    public DBStructure() {
    }

    public DBStructure(String allTypes, String allNames, List<String> allSurfaces, Map<String, Map<String, Unit>> hospitalLayout) {
        setAllTypes(allTypes);
        setAllNames(allNames);
        setAllSurfaces(allSurfaces);
        this.hospitalLayout = hospitalLayout;
    }

    public List<String> getAllTypes() {
        return allTypes;
    }

    public void setAllTypes(String newType) {
        allTypes.add(newType);
    }

    public List<String> getAllNames() {
        return allNames;
    }

    public void setAllNames(String newName) {
        allNames.add(newName);
    }

    public List<String> getAllSurfaces(){
        return allSurfaces;
    }
    public void setAllSurfaces(List<String> surfaces) {
        // Ugly but easy gymnastics to avoid duplicates
        HashSet<String> allSurfacesSet = new HashSet<>(this.allSurfaces);
        for (String surface : surfaces)
            allSurfacesSet.add(surface);
        List<String> allSurfaces = new ArrayList<>(allSurfacesSet);
        this.allSurfaces = allSurfaces;
    }

    public Map<String, Map<String, Unit>> getHospitalLayout() {
        return hospitalLayout;
    }

    public void setHospitalLayout(String unitType, String unitName, long first, long last, List<String> surfaces) {
        Map<String, Map<String, Unit>> hospitalLayout = new HashMap<>();
        Map<String, Unit> nameRoomsSurfaces = new HashMap<>();
        Unit roomsSurfaces = new Unit();
        roomsSurfaces.setUnit(first, last, surfaces);
        nameRoomsSurfaces.put(unitName, roomsSurfaces);
        hospitalLayout.put(unitType, nameRoomsSurfaces);
        this.hospitalLayout = hospitalLayout;

        setAllTypes(unitType);
        setAllNames(unitName);
        setAllSurfaces(surfaces);
    }

    public Map<String, Unit> getUnitNamesRoomsSurfaces(String type, Map<String, Map<String, Unit>> hospitalLayout){
        // Extracts the namesRoomsSurfaces from the HospitalLayout using the passed Type
        Map<String, Map<String, Unit>> layout = hospitalLayout;
        Map<String, Unit> namesRoomsSurfaces = layout.get(type);
        return namesRoomsSurfaces;
    }

    public Unit getRoomsSurfaces (String name, Map<String, Unit> nameRoomsSurfaces){
        return nameRoomsSurfaces.get(name);
    }
}

(Unit 是第二个类,似乎需要在 DBStructure HashMap 中的同一父键下同时具有整数和 List 值)。

    public class Unit {
    // Defines the unit Name-Rooms-Surfaces
    Long firstRoom;
    Long lastRoom;
    List<String> surfaceList = new ArrayList<>();
    //Unit mUnit = new Unit();

    public Unit() {
    }


    public void setUnit (long firstRoom, long lastRoom, List<String> surfaceList) {
        this.firstRoom = firstRoom;
        this.lastRoom = lastRoom;
        this.surfaceList = surfaceList;
    }

    public Long getFirstRoom() {
        return firstRoom;
    }

    public Long getLastRoom() {
        return lastRoom;
    }

    public List<String> getSurfaceList() {
        return surfaceList;
    }

} 

...最后,这是 Firestore 中数据的样子,由一个简单的 .set(mDBStructure) 编写

我感谢任何出于纯粹的利他主义花时间阅读此意大利面条代码的人。

【问题讨论】:

  • DB_STRUCTURE_PATH 的值是多少?
  • 路径有效:毕竟,数据使用 .set(mDBStrucure).... 的路径进入 Firestore。此外,错误消息引用了文档中的第一个字段:allNames。 public static final String DB_STRUCTURE_PATH = "DBStructureCollection/DBStructureDoc";

标签: java android google-cloud-firestore runtime-error


【解决方案1】:

我认为您必须明确指出要反序列化的字段。 例如,在你的情况下,在 onSuccess

DocumentSnapshot document = documentSnapshot.getResult();
DbStructure db = new DbStructure();
db.setAllNames((List<String>) document.get("allNames"));
db.setAllTypes((List<String>) document.get("allTypes"));` 

等等。在那种情况下,当反序列化你的返回对象时,不会有冲突。顺便说一句,在您的设置器中,您必须将参数更改为 List 类型)))。

我没有测试它,我希望它有效))

【讨论】:

  • 感谢您的反馈。为了明确指出我要反序列化的字段将阻止我直接将数据读入对象,而不得不求助于......我想我听说它被称为“原子”或类似的东西,而火力基地文档 (firebase.google.com/docs/firestore/query-data/get-data) 显示了一个示例,其中包含 List 的自定义对象被直接读入该类的变量中。
  • 但是说到这一点,我认为当您谈到我的参数时,您正在做一些事情,需要更改它们,这听起来对我来说是正确的。但据我了解,List 是一个接口,而 ArrayList 是一个类……您能否详细说明您建议的更改?谢谢。
  • 在您的大 POJO 类中,当您设置值时,您通过字符串将值添加到列表中。我建议从 firebase 获取引用时,您将在 setter allNames = firebaseReturnedList 中使用 List 对象来更改引用。
  • ——你完全正确!在程序中进一步进行了一些丑陋,获取一个字符串并将其添加到本地 List,然后将其传递给 setter,然后 addAll() - 但现在对我来说非常有意义。谢谢。
  • 不客气,很高兴它帮助了你。你能接受我的回答吗?)))
猜你喜欢
  • 1970-01-01
  • 2020-08-11
  • 2020-08-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
  • 2013-05-18
相关资源
最近更新 更多