Firebase "Map on deserialization, but got class java.util.ArrayList"

I'm just trying Firebase on Android for my project.

the problem is that every time I take a picture and "drop" it back onto the POJO , I get this -

"Map on deserialization, but received class java.util.ArrayList " Exception.

I looked through and even changed all my models with a HashMap without any ArrayList at all and still got the same result.

Here are my models:

  public class DevicesController { public DevicesCollection devices; public int numberOfport; String timerStatus; public DevicesController(){ devices = new DevicesCollection(); timerStatus = "UPDATED"; } public DevicesController(int numberOfport){ devices = new DevicesCollection(); this.numberOfport = numberOfport; timerStatus = "UPDATED"; } public ArrayList<Integer> getCurrentState(String in){ ArrayList<Integer> currentState = new ArrayList<Integer>(); for(int i = 0; i < numberOfport; i++){ currentState.add(0); } Iterator it = this.getDevices().getAllDevices().entrySet().iterator(); while (it.hasNext()) { Map.Entry pair = (Map.Entry) it.next(); Device temp =(Device)pair.getValue(); if(temp.isOn()){ currentState.set(temp.getPort(),1); }else if(!temp.isOn()){ currentState.set(temp.getPort(),0); } } return currentState; } public String getStringCurrentState(String in){ ArrayList<Integer> currentState = getCurrentState(""); String temp =""; for(int i = 0; i < currentState.size();i++){ temp.concat(""+currentState.get(i)); } return temp; } public void updateToDb(){ Global.dbMRoot.child("devicesController").setValue(this); } public DevicesCollection getDevices() { return devices; } public int getNumberOfport() { return numberOfport; } } public class Category { public String name; public HashMap<String,String> devicesId; public DeviceAlarm categoryAlarm; public Category(){ } public Category(String name) { devicesId = new HashMap<String,String>(); this.name = name; } public void addDevice(Device dev){ devicesId.put(dev.getId(),dev.getId()); } public void removeDevice(Device dev){ devicesId.remove(dev.getId()); } public String getName() { return name; } public void setName(String name) { this.name = name; } public HashMap<String,String> getDevicesId() { return devicesId; } public void setDevicesId(HashMap<String,String> devicesId) { this.devicesId = devicesId; } } public class Device { public String id; public int port; public String name; public boolean on; public DeviceAlarm alarm; public Device(){ } public Device(String id,String name){ this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; updateToDb(); } public String getName() { return name; } public void setName(String name) { updateToDb(); this.name = name; } public boolean isOn() { return on; } public void setOn(boolean on) { updateToDb(); this.on = on; } public void updateToDb(){ Global.dbMRoot.child("devicesController").child("devices").child("allDevice").child(""+id).setValue(this); } public DeviceAlarm getTimer() { return alarm; } public int getPort() { return port; } public void setPort(int port) { updateToDb(); this.port = port; } public DeviceAlarm getAlarm() { return alarm; } public void setAlarm(DeviceAlarm alarm) { Global.dbMRoot.child("devicesController").child("timerStatus").setValue("CHANGED"); this.alarm = alarm; updateToDb(); } public void setAlarm(boolean active, Calendar timeOn, Calendar timeOff) { Global.dbMRoot.child("devicesController").child("timerStatus").setValue("CHANGED"); DeviceAlarm temp = new DeviceAlarm(); temp.setTimeOff(timeOff); temp.setTimeOn(timeOn); this.alarm = temp; updateToDb(); } } package com.lucerna.afgadev.lucerna_maincontroller.Models; import com.lucerna.afgadev.lucerna_maincontroller.Global; import java.util.ArrayList; import java.util.HashMap; /** * Created by aufa on 06/07/2016. */ public class DevicesCollection { public HashMap<String,Device> allDevices; public HashMap<String,Category> categories; int lastId; public DevicesCollection(){ categories = new HashMap<String,Category>(); lastId = 0; allDevices = new HashMap<String, Device>(); } public HashMap<String,Category> getCategories() { return categories; } public HashMap<String,Device> getAllDevices() { return allDevices; } public void addCategory(String name){ categories.put(name,new Category(name)); } public void removeCategory(String name) throws Exception{ int index = -1; for(int i = 0; i< categories.size(); i++){ if(categories.get(i).getName().equals(name)){ index = 1; } } if(index == -1){ throw new Exception("Category not found"); }else{ categories.remove(index); } updateToDB(); } public void updateToDB(){ Global.dbMRoot.child("devicesController").child("devices").setValue(this); } public Category findCategory(String name){ Category temp = null; for(int i = 0; i< this.getCategories().size(); i++){ if(this.getCategories().get(i).getName().equals(name)){ temp = this.getCategories().get(i); } } return temp; } public void switchCategory(String name, boolean on){ Category cat = findCategory(name); for(int i = 0; i < cat.getDevicesId().size();i++){ } } public void addDevice(String name, int port){ Device temp = new Device(); temp.setPort(port); temp.setName(name); allDevices.put(""+lastId,temp); this.lastId++; Global.dbMRoot.child("devicesController").child("devices").child(""+lastId).setValue(allDevices.get(lastId)); } public void removeDevice(int id){ allDevices.remove(id); updateToDB(); } public void setCategoryDevicesAlarm(DeviceAlarm da){ } } 

JSON Tree GDrive sample

I still don't know why this is happening, and I tried to make sure none of them are ArrayList (I know firebase supposedly supports arrayList)

Thanks for all the comments and answers!

+6
source share
3 answers

I have a partial answer, but Frank's expert should explain what is really happening.

Running the published code with version 9.2.0, I noticed that the HashMap for allDevices is stored as a JSON array:

 public class DevicesCollection { public HashMap<String,Device> allDevices; <-- this is stored as array public HashMap<String,Category> categories; int lastId; 

This can be seen in the JSON published by Aufa:

 { "devicesController" : { "devices" : { "allDevices" : [ { <-- note bracket "name" : "", "on" : true, "port" : 0 }, { 

This happens because the keys for allDevices elements are strings as an integer. This is the code that adds an entry to the allDevices card:

 public void addDevice(String name, int port){ Device temp = new Device(); temp.setPort(port); temp.setName(name); allDevices.put(""+lastId,temp); <-- Note that lastId is an integer this.lastId++; Global.dbMRoot.child("devicesController").child("devices").child(""+lastId).setValue(allDevices.get(lastId)); } 

If this code is modified to use a string key that is not in an integer format, for example:

 allDevices.put("ID"+lastId,temp); 

Then the display is recorded in the form of a map and can be read using

 getValue(DevicesCollection.class); 
+6
source

Firebase is interpreted as ArrayList, if the key is only numeric, add before one line, for example:

Base dados da firebase interpa como ArrayList se chave for apenas numérica, adicione antes uma String, example:

 map.put("OneString"+number, object); 
+2
source

It works for me

1st model of Create Firebase:

 public class PointsRound { private static final String ID_PREFIX = "ID_"; @PropertyName("pointsSecond") HashMap<String, String> pointsSecond; public PointsRound() { //default constructor for firebase parser } public HashMap<String, String> getPointsSecond() { HashMap<String, String> convertTo = new HashMap<>(); if (pointsSecond.entrySet().iterator().hasNext()) { Map.Entry<String, String> entry = pointsSecond.entrySet().iterator().next(); //(!)TRIM PREFIX HERE: convertTo.put(entry.getKey().replaceFirst(ID_PREFIX, ""), entry.getValue()); } else { return pointsSecond; } return convertTo; } public void setPointsSecond(HashMap<String, String> pointsSecond) { this.pointsSecond = pointsSecond; } @Exclude public Map<String, Object> toMap() { HashMap<String, Object> result = new HashMap<>(); HashMap<String, String> convertSecondToFierebaseFormat = new HashMap<>(); if (pointsSecond.entrySet().iterator().hasNext()) { Map.Entry<String, String> entry = pointsSecond.entrySet().iterator().next(); //(!)ADD PREFIX HERE: convertSecondToFierebaseFormat.put(ID_PREFIX + entry.getKey(), entry.getValue()); this.pointsSecond = convertSecondToFierebaseFormat; } result.put("pointsSecond", convertSecondToFierebaseFormat); return result; } } 

2nd model Save to Firebse:

  private static final String RESULT_ROUND_MATCH = "result-round-match"; private DatabaseReference refDb = getDatabase().getReference(); public void savepointRoundFirebase(PointRound pontRound){ Map<String, Object> childUpdates = new HashMap<>(); Map<String, Object> valuesMatchResult = pontRound.toMap(); childUpdates.put("/" + RESULT_ROUND_MATCH,valuesMatchResult); refDb.updateChildren(childUpdates); } 

got this result in firebase

3rd download result

  private static final String RESULT_ROUND_MATCH = "result-round-match"; @Override public void loadData(final IDataWorkerCallback dataWorkerCallback) { Query lotsIdQuery = refDb.child(RESULT_ROUND_MATCH); lotsIdQuery.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { PointsRound pointRound = dataSnapshot.getValue(PointsRound .class); dataWorkerCallback.loadedMixResult(fighterGroupFBs); } @Override public void onCancelled(DatabaseError databaseError) { } }); } 
0
source

All Articles