【问题标题】:"No setter/field for field found on class"“在课堂上找不到字段的设置器/字段”
【发布时间】:2018-06-05 18:02:16
【问题描述】:

我正在 Android Studio 中创建一个连接到 Cloud Firestore 数据库的应用。在数据库中,我有以下结构:

Myclass
  - name = "test"
  - subclass
     - 0 = "String 1"
     - 1 = "String 2"

类本身是这样声明的(删除了不相关的位):

public class Myclass {

    private String name;
    private String[] subclass;

    // CONSTRUCTOR
    public Chart() {}

    //GETTERS
    public String getName()     { return this.name; }

    // SETTERS
    public void setSubclass(String[] thisSubclass)    { this.subclass = thisSubclass; }

}

在活动中,Myclass 对象是这样设置的(同样,不相关的位被删除):

public class MyclassActivity  {
    DocumentReference docRef;
    Myclass myItem;

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

       // Set up database connection, read in itemId etc...
       // ...omitted for clarity...    

        docRef = databaseRef.collection("myclass").document(itemId);
        docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        myItem = document.toObject(Myclass.class);
                    }
                }
         }
}

这会读入 Myclass 对象,名称设置正确,但子类对象没有设置 - 它仍然为空。

在调试控制台中有以下消息:

No setter/field for subclass found on class path.to.app.Myclass

“setSubclass”函数显示为灰色,就好像它从未使用过一样。我确定问题很明显,但我看不到。

【问题讨论】:

  • 为什么不尝试将子类字段设为列表而不是数组? private List&lt;String&gt; subclass;
  • 试过了 - 它没有任何区别。除非我应该对数据库中的数据结构做点什么?
  • 这是一个键值对吗? - 子类 - 0 = “字符串 1” - 1 = “字符串 2”

标签: java android firebase google-cloud-firestore


【解决方案1】:

您现在的问题是您的类名必须与构造函数相同。您还需要将getter 添加到您的subclass 参数中。

public class Chart {

   private String name;
   private String[] subclass;

   public Chart() {
   //Default empty constructor, required for Firebase.
   }

   public Chart(String name, String[] subclass) {
       this.name = name;
       this.subclass = subclass;
   }

   public String getName() {
      return this.name;
   }

   public String[] getSubclass() {
      return subclass;
   }
}

另一方面,您不需要添加设置器。它们不是必需的。 Firebase 会将值设置到该字段中。但是,如果您要从外部与班级互动,则应该添加它们。

在某些情况下,您希望在参数上使用不同的名称,可能是因为您想遵循驼峰命名法或其他方式。如果是这种情况,您可以使用注释 @PropertyName 在数据库中提供不同的名称,并根据需要保留模型。例如:

public class Chart {

   @PropertyName("name")
   private String mName;
   @PropertyName("subclass")
   private String[] mSubclass;

   public Chart() {
   }

   @PropertyName("name")
   public String getmName() {
      return mName;
   }

   @PropertyName("subclass")
   public String[] getmSubclass() {
      return mSubclass;
   }
}

【讨论】:

    【解决方案2】:

    您的模型类中有两个错误。第一个是构造函数的名称,它与类的名称不同并且应该相同。第二,对于 subclass 字段,您只定义了 setter,但没有定义 getter。

    您的Myclass 类应该如下所示:

    public class MyClass {
        private String name;
        private String[] subclass;
    
        public MyClass() {}
    
        public MyClass(String name, String[] subclass) {
            this.name = name;
            this.subclass = subclass;
        }
    
        public String getName() { return name; }
    
        public String[] getSubclass() { return subclass; }
    }
    

    不需要设置器。如果 JSON 属性没有设置器,Firebase 客户端会将值直接设置到字段上,这就是为什么称为惯用的。如果您在代码中明确需要它们,只需将以下设置器添加到您的模型类中,如下所示:

    public void setName(String name) { this.name = name; }
    
    public void setSubclass(String[] subclass) { this.subclass = subclass; }
    

    关于 Cloud Firestore 数据库中数组的使用,请看我在这个post的回答。

    【讨论】:

    • 谢谢!我将其更改为 List(所以 List 而不是 String[])并添加了一个 Getter,并且它起作用了。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 2020-03-06
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多