我只是在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)
感谢您的所有评论和回答!
我有一个部分答案,但需要弗兰克的专业知识来解释到底发生了什么。
使用版本 9.2.0 运行发布的代码,我观察到allDevices
的HashMap
存储为 JSON 数组:
public class DevicesCollection {
public HashMap<String,Device> allDevices; <-- this is stored as array
public HashMap<String,Category> categories;
int lastId;
这在Aufa发布的JSON中可见:
{
"devicesController" : {
"devices" : {
"allDevices" : [ { <-- note bracket
"name" : "",
"on" : true,
"port" : 0
}, {
这似乎是因为allDevices
元素的键是整数形式的字符串。 这是向allDevices
映射添加条目的代码:
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));
}
如果将此代码修改为使用非整数格式的 String 键,例如:
allDevices.put("ID"+lastId,temp);
然后将地图写成地图,可以使用
getValue(DevicesCollection.class);
我也遇到了同样的错误。但后来我才知道,起初,我在 Note.kt
数据类中使用了 List 的 tags
变量并将其存储在 firestore 文档中,但后来我用 Map tags
更改了相同的变量名称并尝试从 firestore 获取数据。在 firestore 中,我与列表和地图tags
名称相同,因此在从 firestore 获取数据时出现错误。当我删除集合并再次添加数据时,我的问题解决了。
注意.kt
data class Note(
//val tags:List<String>? = null, //first with tags variable
val tags:Map<String,Any>? = null, //second with same tags variable
)
如果你像这样映射:
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)
}
})
我的用户项类:
@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
)
或者你可以看看这个 链接.火力部队使用地图而不是阵列