"Нет сеттера / поля для поля, найденного в классе"

Sharon спросил: 12 мая 2018 в 04:22 в: java

Я создаю приложение в 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 greyed out , как будто он никогда не использовался. Я уверен, что проблема - это нечто очевидное, но я не вижу этого.

2 ответа

Есть решение
Alex Mamo ответил: 13 мая 2018 в 06:06

У вас есть две ошибки в вашем классе модели. Первым будет имя конструктора, который отличается от имени класса и должен быть тем же. И второе, для поля 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, см. Мой ответ из этого сообщения .

Alex Mamo ответил: 14 мая 2018 в 05:53
Вы пробовали мое решение выше, это работает?
Sharon ответил: 14 мая 2018 в 02:01
Благодаря! Я изменил его на список (поэтому List < String > вместо String []) и добавил Getter, и он сработал. Спасибо за помощь!
Alex Mamo ответил: 14 мая 2018 в 02:02
Приятно слышать, что это сработало! Пожалуйста, Шарон! Если вы думаете, что мой ответ помог вам, подумайте о том, чтобы принять его. Благодаря!
halfer Francisco Durdin Garcia ответил: 01 июня 2018 в 08:14

Ваша проблема прямо сейчас заключается в том, что ваше имя класса должно быть таким же, как конструктор. Также вам нужно добавить 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 установит значение в поле. Но вы должны добавить их, если вы собираетесь взаимодействовать с классом извне.

Будут случаи, когда вы хотите иметь разные имена по своим параметрам, возможно, потому, что вы хотите следовать номенклатуре camelCase или что-то. Если это так, вы можете использовать аннотацию @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;
   }
}
Sharon ответил: 14 мая 2018 в 02:01
Спасибо! Добавление Геттера, похоже, делало трюк.