我只是在Android上为我的项目尝试Firebase。
我得到的问题是,每次拍摄快照并将其“投”回 POJO 我都会得到这个 -
“在反序列化时映射,但得到了一个类java.util.ArrayList
”例外。
我一直在环顾四周,甚至根据HashMap
使用ArrayList
更改我的所有模型,但仍然得到相同的结果。
以下是我的模特:
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树GDrive
我仍然不知道它为什么会发生,我已经重新检查以确保没有一个是ArrayList(我知道firebase假设支持arrayList)
感谢所有的评论和答案!
答案 0 :(得分:10)
我有一个部分答案,但需要弗兰克的专业知识来解释实际情况。
使用版本9.2.0运行发布的代码,我发现HashMap
的{{1}}存储为JSON数组:
allDevices
这在Aufa发布的JSON中可见:
public class DevicesCollection {
public HashMap<String,Device> allDevices; <-- this is stored as array
public HashMap<String,Category> categories;
int lastId;
这似乎是因为{
"devicesController" : {
"devices" : {
"allDevices" : [ { <-- note bracket
"name" : "",
"on" : true,
"port" : 0
}, {
元素的键是整数形式的字符串。这是在allDevices
:
allDevices
如果修改此代码以使用非整数格式的String键,例如:
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));
}
然后地图被写成地图,可以使用
读取allDevices.put("ID"+lastId,temp);
答案 1 :(得分:0)
如果您要这样映射:
basketRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if(dataSnapshot.value==null || dataSnapshot.value!!.equals(""))
Enums.userBasket=UserItem()
else
Enums.userBasket = dataSnapshot.getValue(UserItem::class.java)
}
override fun onCancelled(p0: DatabaseError) {
// Failed to read value
Log.d(TAG, "Error= "+p0.message)
}
})
在Firebase设备中,id元素元素为(-1:"",-2:"")
Firebase Android SDK看到这是一个ArrayList而不是Map Object。
以下代码对我来说很好。我不能使用上面的代码。
Enums.userBasket=UserItem()
basketRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if(dataSnapshot.value==null || dataSnapshot.value!!.equals(""))
else{
if(dataSnapshot.child("books")!=null){
dataSnapshot.child("books").children.forEach {
Enums.userBasket!!.books[it.key.toString()] =it.value.toString()
}
}
if(dataSnapshot.child("cards")!=null){
dataSnapshot.child("cards").children.forEach {
Enums.userBasket!!.cards[it.key.toString()] =it.value.toString()
}
}
if(dataSnapshot.child("exams")!=null){
dataSnapshot.child("exams").children.forEach {
Enums.userBasket!!.exams[it.key.toString()] =it.value.toString()
}
}
}
}
override fun onCancelled(p0: DatabaseError) {
// Failed to read value
Log.d(TAG, "Error= "+p0.message)
}
})
我的UserItem类:
@IgnoreExtraProperties
data class UserItem(
var books:MutableMap<String,String> = HashMap(),//id,value
var cards:MutableMap<String,String> = HashMap(),//id,value
var exams:MutableMap<String,String> = HashMap()//id,value
)
或者您可以查看此链接。 Firebase force to use map rather than array
答案 2 :(得分:0)
我也有同样的错误。但后来我才知道,起初,我在我的 tags
数据类中为 List 使用了 Note.kt
变量并将其存储在 firestore 文档中,但后来我更改了相同的变量名称 tags
使用 Map 并尝试从 firestore 获取数据。在 firestore 中,我的名称 tags
与 List 和 Map 相同,因此在从 firestore 获取数据时出现错误。当我删除集合并再次添加数据时,我的问题解决了。
Note.kt
data class Note(
//val tags:List<String>? = null, //first with tags variable
val tags:Map<String,Any>? = null, //second with same tags variable
)