Java 无法从Firestore读取自定义对象--为什么?
我收到了这个错误消息 java.lang.RuntimeException:无法反序列化对象。未能将java.util.ArrayList类型的值转换为字符串(在字段“AllName”中找到) 当我试图将文档从Firestore读入自定义对象DBStructure.class时Java 无法从Firestore读取自定义对象--为什么?,java,android,google-cloud-firestore,runtime-error,Java,Android,Google Cloud Firestore,Runtime Error,我收到了这个错误消息 java.lang.RuntimeException:无法反序列化对象。未能将java.util.ArrayList类型的值转换为字符串(在字段“AllName”中找到) 当我试图将文档从Firestore读入自定义对象DBStructure.class时 public class DBStructure { List<String> allTypes = new ArrayList<>(); List<String&
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);
}
}
以下是我用来检索数据的代码:
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());
}
});
}
私有FirebaseFirestore db=FirebaseFirestore.getInstance();
私有文档引用DBStructureDocRef=db.document(db\u结构\u路径);
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRoom=新房间();
mDBStructure=新的DBStructure();
readData();
HandleSpinnerSelection(“,-1”);
}
私有void readData(){
DBStructureDocRef.get()
.addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时公共无效(文档快照文档快照){
if(documentSnapshot.exists()){
**mDBStructure=documentSnapshot.toObject(DBStructure.class)**;
}
}
})
.addOnFailureListener(新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常e){
Toast.makeText(MainActivity.this,“Error!”,Toast.LENGTH_SHORT.show();
Log.d(标记,例如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);
}
}
公共类数据库结构{
List allTypes=new ArrayList();
List allNames=new ArrayList();
List allSurfaces=new ArrayList();
Map hospitalLayout=新建HashMap();
公共数据库结构(){
}
公共数据库结构(字符串所有类型、字符串所有名称、列表所有曲面、地图医院布局){
设置所有类型(所有类型);
设置所有名称(所有名称);
设置所有表面(所有表面);
this.hospitalLayout=hospitalLayout;
}
公共列表getAllTypes(){
返回所有类型;
}
public void setAllTypes(字符串newType){
添加(newType);
}
公共列表getAllNames(){
返回所有名称;
}
public void setAllName(字符串newName){
allNames.add(newName);
}
公共列表getAllSurfaces(){
返回所有表面;
}
公共void setAllSurfaces(列出曲面){
//丑陋但简单的体操,以避免重复
HashSet allsurfaceset=新的HashSet(this.allSurfaces);
用于(字符串曲面:曲面)
所有表面设置。添加(表面);
列出所有表面=新阵列列表(AllSurfaceSet);
this.allSurfaces=所有曲面;
}
公共地图getHospitalLayout(){
返回医院;
}
public void setHospitalLayout(字符串单位类型、字符串单位名称、长首、长尾、列表曲面){
Map hospitalLayout=新建HashMap();
Map nameRoomsSurfaces=新建HashMap();
单元房间表面=新单元();
RoomsSurface.setUnit(第一个、最后一个、曲面);
nameRoomsSurfaces.put(unitName,roomsSurfaces);
hospitalLayout.put(单元类型、名称、房间表面);
this.hospitalLayout=hospitalLayout;
SetAllType(unitType);
setAllName(unitName);
设置所有曲面(曲面);
}
公共地图GetUnitNamesRoomsSurface(字符串类型,地图医院布局){
//使用传递的类型从HospitalLayout提取NamesRoomsSurface
地图布局=医院布局;
MapNamesRoomsSurFaces=layout.get(类型);
返回namesroomsSurface;
}
公共单元GetRoomsSurface(字符串名称、映射名称RoomsSurface){
返回NameRoomsSurface.get(name);
}
}
(Unit是第二个类,在DBStructure HashMap中,在同一父键下同时具有整型值和列表值似乎是必需的)
公共类单元{
//定义房间曲面的单元名称
长第一间房;
长尾房;
List surfaceList=new ArrayList();
//单位mUnit=新单位();
公共单位(){
}
公共空间集合单元(长第一个房间、长最后一个房间、列表表面列表){
this.firstRoom=firstRoom;
this.lastRoom=lastRoom;
this.surfaceList=surfaceList;
}
公共长廊{
返回第一个房间;
}
公共长廊{
返回最后一个房间;
}
公共列表getSurfaceList(){
回归表面主义者;
}
}
…最后,这里是Firestore中的数据,由一个简单的.set(mDBStructure)编写
我感谢那些纯粹出于利他主义而花时间阅读此意大利面代码的人。我认为你必须明确指出你要反序列化的领域。 例如,在您的案例中,inside onSuccess
DocumentSnapshot document = documentSnapshot.getResult();
DbStructure db = new DbStructure();
db.setAllNames((List<String>) document.get("allNames"));
db.setAllTypes((List<String>) document.get("allTypes"));`
DocumentSnapshot document=DocumentSnapshot.getResult();
DbStructure db=新的DbStructure();
db.setAllNames((List)document.get(“allNames”);
db.setAllTypes((列表)document.get(“所有类型”);`
等等。在这种情况下,当反序列化返回的对象时,不会有冲突。顺便说一下,在setters中,必须将参数更改为List type)
我没有测试它,我希望它能工作)DB_STRUCTURE_PATH的值是多少?路径能工作:毕竟,数据是通过.set(mdbstructure)路径进入firestore的……此外,错误消息引用了文档中的第一个字段:allNames。公共静态最终字符串DB\u STRUCTURE\u PATH=“DBStructureCollection/DBStructureDoc”;谢谢你的反馈。具体指出我正在反序列化的字段将阻止我直接将数据读入对象,而不是