我有一个 User
类,它保存一些有关用户的额外数据。此数据存储在/来自 Firestore。我有几个正在工作的字段(name
、surname
、lastLogin
),但其中几个不工作(blocked
)。
当我将字段公开时,它们可以工作,但是当我尝试使用 setter 时,它们就不起作用。我尝试清理构建并重建它。我知道由于 @Exclude
,它没有保存该字段,这是有意的。
我做错了什么?字段类型并不重要,我添加了一个新的 String
字段,该字段给出了相同的警告,而 name
和 surname
则有效。
数据库:
**userid**
{
"name" : "John",
"surname" : "Doe",
"lastLogin" : **timestamp**,
"blocked" : true
}
类(class):
@Keep
public class User
{
private String name;
private String surname;
private Date lastLogin;
private boolean blocked = false;
public User()
{
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getSurname()
{
return surname;
}
public void setSurname(String surname)
{
this.surname = surname;
}
public Date getLastLogin()
{
return lastLogin;
}
public void setLastLogin(Date lastLogin)
{
this.lastLogin = lastLogin;
}
@Exclude
public boolean isBlocked()
{
return blocked;
}
public void setBlocked(boolean blocked)
{
this.blocked = blocked;
}
最佳答案
代码中的问题是 User
类中的构造函数是私有(private)。这不是创建该类的新实例的正确方法。 JavaBeans require a no-argument constructor出席。
当 Cloud Firestore SDK 反序列化来自数据库的对象时,它要求任何正在使用的对象都具有此公共(public)无参构造函数,以便可以使用它来实例化该对象。正如您已经尝试过的那样,对象中的字段是通过使用公共(public) setter 方法或直接访问公共(public)成员来设置的。
因为您的构造函数是私有(private)的,所以 SDK 并不真正知道如何创建它的实例。因此必须将其更改为公开。创建该类的正确方法应该是:
class User {
private String name;
private String surname;
private long lastLogin;
private boolean blocked = false;
public User() {} //Needed for Cloud Firestore
public User(String name, String surname, long lastLogin, boolean blocked) {
this.name = name;
this.surname = surname;
this.lastLogin = lastLogin;
this.blocked = blocked;
}
//Getters and setters are not mandatory
}
另请注意,setter 和 getter 不是必需的。 Setter 始终是可选的,因为如果 JSON 属性没有 setter,Firebase 客户端会将值直接设置到字段上。
编辑:
根据您的评论:
but it does not explain why some fields are working and others aren't. It should not work at all, right?
是的,没错,一切都应该有效。其中一些不起作用的原因是 User
类中的 blocked
属性是 boolean
类型,而数据库中的属性是 boolean
类型String
这是不正确的。两种类型必须匹配。
And the private constructor is due to the singleton instance, as far as I know, the constructor should be private to avoid creating new instances of the class.
不可以,构造函数必须是公共(public)的。我认为这其中存在误会。每次使用 FirebaseDatabase.getInstance()
时,您的应用程序和 Firebase 服务器之间都会打开一个套接字连接。从那时起,应用程序和数据库之间的所有流量都通过同一个套接字。因此,无论您创建实例多少次,它始终是单个连接。对于 POJO 类,不需要这样的 Singleton,因为 Firebase 始终需要知道如何使用公共(public)无参构造函数创建该类的实例。
关于java - Firestore : (21. 4.1) [CustomClassMapper]:没有 setter /字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60822242/