This line:
ProjectMap m = document.toObject(ProjectMap.class);
Generates the error:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.dockdogs.lorecoords, PID: 5633 java.lang.RuntimeException: Could not deserialize object. Class com.dockdogs.lorecoords.preferences.MapPreference$Bubble does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped (found in field 'preferences.mapBubble') at com.google.firebase.firestore.util.CustomClassMapper.deserializeError(CustomClassMapper.java:563) at com.google.firebase.firestore.util.CustomClassMapper.access$200(CustomClassMapper.java:54) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:749) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:741) at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:542) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:253) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(CustomClassMapper.java:189) at com.google.firebase.firestore.util.CustomClassMapper.access$300(CustomClassMapper.java:54) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:778) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:741) at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:542) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:253) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(CustomClassMapper.java:189) at com.google.firebase.firestore.util.CustomClassMapper.access$300(CustomClassMapper.java:54) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:770) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:741) at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:542) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:253) at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:100) at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:183) at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:116) at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:161) at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:97) at com.dockdogs.lorecoords.SaveSystem$26.onComplete(SaveSystem.java:488) at com.google.android.gms.tasks.zzj.run(com.google.android.gms:play-services-tasks@@17.2.0:4) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8512) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
ProjectMap just looks like:
public class ProjectMap implements Serializable {
public int height=0;
public int width=0;
public String id = "";
public int scaleRatio = 1; //FOR ZOOMING THE MAP IN AND OUT
public String mapTitle, mapPath; //map path = image path
public boolean ISCURRENT = false; //the map that's currently being used by the user
public ArrayList<MapEvent> mapEvents = new ArrayList<MapEvent>();
private MapPreference preferences = new MapPreference();
}
... and MapPreferences looks like:
public class MapPreference implements Serializable {
//Controls scale for map bitmap
public float minScaleX = 0.50f;
public float maxScaleX = 8f;
public float minScaleY = 0.50f;
public float maxScaleY = 8f;
//end controls for scaling map bitmap
public Dagger mapDagger = new Dagger();
public Bubble mapBubble = new Bubble();
public boolean useGridLines = true;
public int gridCols = 0;
public int gridRows = 0;
public MapPreference() {
}
public void setGridRows(int gridRows) { this.gridRows = gridRows; }
public void setGridCols(int gridCols) { this.gridCols = gridCols; }
//will the user have grid lines on their map?
public void setUseGridLines(boolean useGridLines) { this.useGridLines = useGridLines; }
public boolean GetUseGridLines() { return useGridLines; }
public int GetGridCols(){
return gridCols;
}
public int GetGridRows(){
return gridRows;
}
public float GetMinScaleX(){
return minScaleX;
}
public float GetMinScaleY(){
return minScaleY;
}
public float GetMaxScaleX(){
return maxScaleX;
}
public float GetMaxScaleY(){
return maxScaleY;
}
//TODO: add a preferences page for these options
public void SetMinScaleX(float _minScaleX){
minScaleX = _minScaleX;
}
public void SetMinScaleY(float _minScaleY){
minScaleY = _minScaleY;
}
public void SetMaxScaleX(float _maxScaleX){
maxScaleX = _maxScaleX;
}
public void SetMaxScaleY(float _maxScaleY){
maxScaleY = _maxScaleY;
}
public class Dagger implements Serializable {
public float minScaleX = 0.75f;
public float maxScaleX = 1f;
public float minScaleY = 0.75f;
public float maxScaleY = 1f;
public float GetMinScaleX(){
return minScaleX;
}
public float GetMinScaleY(){
return minScaleY;
}
public float GetMaxScaleX(){
return maxScaleX;
}
public float GetMaxScaleY(){
return maxScaleY;
}
//TODO: add a preferences page for these options
public void SetMinScaleX(float _minScaleX){
minScaleX = _minScaleX;
}
public void SetMinScaleY(float _minScaleY){
minScaleY = _minScaleY;
}
public void SetMaxScaleX(float _maxScaleX){
maxScaleX = _maxScaleX;
}
public void SetMaxScaleY(float _maxScaleY){
maxScaleY = _maxScaleY;
}
public Dagger(){
}
}
public class Bubble implements Serializable {
public float minScaleX = 0.75f;
public float maxScaleX = 1f;
public float minScaleY = 0.75f;
public float maxScaleY = 1f;
public float GetMinScaleX(){
return minScaleX;
}
public float GetMinScaleY(){
return minScaleY;
}
public float GetMaxScaleX(){
return maxScaleX;
}
public float GetMaxScaleY(){
return maxScaleY;
}
//TODO: add a preferences page for these options
public void SetMinScaleX(float _minScaleX){
minScaleX = _minScaleX;
}
public void SetMinScaleY(float _minScaleY){
minScaleY = _minScaleY;
}
public void SetMaxScaleX(float _maxScaleX){
maxScaleX = _maxScaleX;
}
public void SetMaxScaleY(float _maxScaleY){
maxScaleY = _maxScaleY;
}
public Bubble() {
}
}
}
I wonder if the floats are failing to retrieve properly with Firestore, but if that's true I'm not sure what I can do about it.
ALSO THIS ISN'T A DUPLICATE QUESTION BECAUSE THE CLASS ALREADY HAS AN EMPTY CONSTRUCTOR AND IT STILL THROWS THE ERROR.