java - Firestore : (21. 4.1) [CustomClassMapper]:没有 setter /字段

标签 java android firebase google-cloud-firestore pojo

我有一个 User 类,它保存一些有关用户的额外数据。此数据存储在/来自 Firestore。我有几个正在工作的字段(namesurnamelastLogin),但其中几个不工作(blocked )。

当我将字段公开时,它们可以工作,但是当我尝试使用 setter 时,它们就不起作用。我尝试清理构建并重建它。我知道由于 @Exclude ,它没有保存该字段,这是有意的。

我做错了什么?字段类型并不重要,我添加了一个新的 String 字段,该字段给出了相同的警告,而 namesurname 则有效。

数据库:

**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/

相关文章:

android - 抽屉导航中的可折叠列表项

android - LiveData 不会将类型推断为所需的返回值

java - 尝试写入文档是否会消耗 Cloud Firestore 中的写入操作成本?

java - Selenium 网络驱动程序 Java : improve "if else" performance?

java - 如何将 i-jetty 服务器嵌入到 android 应用程序中?

java - 使用Tomcat启动Spring Boot时的用户名和密码是什么?

android - 仅发布 7 英寸和 10 英寸平板电脑的 Android 应用程序

java - 在 Activity 之间传递 ResourceId 作为整数

javascript - Angularjs 两阶段解析(解决依赖关系)

java - 在 vlcj 中播放实时 http 流