Firebase getValue() никогда не заканчивается

У меня проблема с администратором Firebase с Java. Я использую базу данных Firebase Realtime, и мне нужно прочитать данные в конкретном дочернем элементе моей базы данных. Проблема в том, что я использую ValueEventListener для чтения данных, но getValue() в onDataChange никогда не заканчивается или никогда не выполняется. Я пытаюсь преобразовать DataSnapshot в определенный объект в моей модели (который имеет непримитивные объекты в качестве атрибутов). Я пытаюсь сделать это:

System.out.println(dataSnapshot.getValue(MyObject.class).toString());

но ничего не печатается! Я также пытался сделать этот вызов (а затем использовать, например, gson):

System.out.println(dataSnapshot.getValue(JSONObject.class).toString());

но ничего не печатается снова. Этот код находится в onDataChange моего ValueEventListener. Я также попытался напечатать все дочерние атрибуты элемента, и у меня нет проблем, но если я попытаюсь вызвать getValue (MyObject.class), ничего не произойдет. Я на Heroku с Spring.

В чем моя ошибка?

[EDIT]: это атрибут в базе данных, который я хочу получить:

"ricette" : {
    "-L2yUEiCOkxn4zLISjOm" : {
      "a" : true,
      "approvata" : 1516098247226,
      "autore" : {
        "displayname" : "Matteo",
        "id" : "CaOUusrQLFQDW0rvnC0xkiEBSv42"
      },
      "carboidrati" : 42.584,
      "chiave" : "-L2yUEiE-Zos_y1GcRrv",
      "id" : "-L2yUEiCOkxn4zLISjOm",
      "image" : "url_to_image",
      "ingredienti" : [ {
        "alimento" : {
          "carboidrati" : 1.4,
          "cod" : "1316_2",
          "id" : "9506094d-9986-46a2-b825-c5ad174b936e",
          "kcal" : 57,
          "lipidi" : 1,
          "nome" : "POLPO",
          "proteine" : 10.6,
          "ratio" : 0.08
        },
        "quantita" : 1000
      }, {
        "alimento" : {
          "carboidrati" : 11.4,
          "cod" : "100180_1",
          "id" : "0b520eee-fada-44c6-9544-0072bd8634bc",
          "kcal" : 55,
          "lipidi" : 0.4,
          "nome" : "POMODORO, CONCENTRATO (sostanza secca 18%)",
          "proteine" : 0.9,
          "ratio" : 0.03
        },
        "quantita" : 250
      }, {
        "alimento" : {
          "carboidrati" : 8.4,
          "cod" : "301_1",
          "id" : "44f1b140-b40d-436c-80c7-0ba336c64045",
          "kcal" : 45,
          "lipidi" : 0.6,
          "nome" : "AGLIO, fresco",
          "proteine" : 0.9,
          "ratio" : 0.06
        },
        "quantita" : 1
      }, {
        "alimento" : {
          "carboidrati" : 0,
          "cod" : "338_1",
          "id" : "7077bfc1-bc63-48ea-8647-c596da34416f",
          "kcal" : 30,
          "lipidi" : 0.6,
          "nome" : "PREZZEMOLO, fresco",
          "proteine" : 3.7,
          "ratio" : 0.16
        },
        "quantita" : 10
      } ],
      "inviata" : 1516098091939,
      "kcal" : 710.95,
      "lipidi" : 11.066,
      "nome" : "Polpo in umido",
      "note" : "Nota sul polpo in umido",
      "portata" : "Secondo",
      "proteine" : 108.629,
      "ratio" : 0.07
    }

Это классы Java в моей модели:

    public class Ricetta implements Serializable {

        private User.Autore autore;
        private String id;
        private String nome;
        private String portata;
        private String note;

        private ArrayList<Alimento.Ingrediente> ingredienti;

        private double lipidi;
        private double proteine;
        private double carboidrati;
        private double kcal;
        private double ratio;
    }

    public class Alimento implements Serializable {

        public Alimento() {
        }

        private String id;
        private String cod;
        private String nome;
        private boolean aggiuntodautente;

        private double lipidi;
        private double proteine;
        private double carboidrati;
        private double kcal;
        private double ratio;
    }



    public class Ingrediente implements Serializable {

        public Ingrediente() {
        }

        private Alimento alimento;
        private int quantita;
}

    public class Autore implements Serializable {

        public Autore() {
        }

        public Autore(String displayname, String id) {
            this.setDisplayname(displayname);
            this.setId(id);
        }

        private String displayname;
        private String id;
}

Это объект, в частности:

public class RicettaG extends Ricetta implements Serializable {

    private String chiave;
    private String image;

    private long inviata;
    private boolean a;
    private long approvata;

}

(со всеми геттерами и сеттерами) Проблема с вызовом dataSnapshot.getValue(RicettaG.class) в ссылке database.getReference("ricette/-L2yUEiCOkxn4zLISjOm"). Может быть проблема в том, что в базе нет атрибута aggiuntodautente? Спасибо.


person manzi    schedule 09.02.2018    source источник
comment
Пожалуйста, добавьте свой класс модели и структуру базы данных.   -  person Alex Mamo    schedule 09.02.2018
comment
Вызов getValue не блокируется; он не может зависнуть (если не считать ошибки). Здесь недостаточно кода, чтобы увидеть, что вызывает вашу проблему. Прочтите как создать минимальный полный проверяемый пример. Быстрое предположение состоит в том, что это будет включать в себя то, как вы подключаете прослушиватель, к чему вы присоединяетесь (как спросил Алекс) и как вы обрабатываете данные от прослушивателя в остальной части вашего кода.   -  person Frank van Puffelen    schedule 09.02.2018
comment
Добавлены классы моделей и структуры базы данных, мне очень жаль, это мой первый вопрос о переполнении стека, спасибо   -  person manzi    schedule 09.02.2018


Ответы (1)


Когда вы используете следующую строку кода:

System.out.println(dataSnapshot.getValue(MyObject.class).toString());

Очевидно, вы пытаетесь распечатать данные из базы данных, но это не так. Вы получаете объект своего класса модели, а затем переводите его в строку, что не имеет смысла, поскольку вы не переопределяете метод toString() в своем классе модели. На самом деле вы печатаете адрес вашего объекта MyObject из памяти.

При использовании следующей строки кода:

System.out.println(dataSnapshot.getValue(JSONObject.class).toString());

Также неправильно. Вы не можете получить объект типа JSONObject, используя метод getVaue() для объекта dataSnapshot. И опять же, приведение его к String вообще не имеет никакого смысла.

Предполагая, что ваш узел ricette является прямым дочерним элементом вашего корня Firebase, используйте следующий код:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ricetteRef = rootRef.child("ricette");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            Ricetta ricetta = ds.getValue(Ricetta.class);
            System.out.println(ricetta.getNome());
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
ricetteRef.addListenerForSingleValueEvent(eventListener);

На выходе будут все значения свойства nome.

person Alex Mamo    schedule 10.02.2018
comment
Спасибо, но мне нужно получить объект RicettaG (который расширяет Ricetta), и когда я пытаюсь вызвать что-то вроде RicettaG ricetta = ds.getValue(RicettaG.class); он никогда не заканчивается (это не в коде, о котором я сообщил, а в коде, который я добавил в один из сделанных мной тестов, я перезаписал метод toString() в модели). Может проблема в том, что RicettaG расширяет Ricetta? Идея состоит в том, что я хочу получить карту ‹String, RicettaG› из узла risette в базе данных. Спасибо. - person manzi; 11.02.2018
comment
Затем создайте объект RicettaG внутри класса вашей модели, добавьте сеттеры и геттеры и все. Если вам нужна карта ‹String, RicettaG›, используйте класс String вместо класса модели. - person Alex Mamo; 12.02.2018
comment
RicettaG уже присутствует как расширение Ricetta, мне нужно переместить RicettaG как внутренний класс Ricetta? В обоих классах моделей есть все геттеры и сеттеры, когда я вызываю getValue (RicettaG.class), я хотел бы получить все атрибуты Ricetta + атрибуты, присутствующие RicettaG, которые расширяют Ricetta. На данный момент я использовал обходной путь, но я действительно хочу знать, в чем моя ошибка... Большое спасибо за вашу помощь! - person manzi; 18.02.2018
comment
Да, войдите внутрь и попробуйте еще раз. Это так работает? - person Alex Mamo; 18.02.2018
comment
RicettaG перемещен как внутренний класс Ricetta, это не работает... Я добавил много System.out.println() в любой точке, но dataSnapshot.getValue(Ricetta.RicettaG.class); ничего не делает. (теперь это Ricetta.RicettaG.class, потому что я переместил один класс в другой) Что мне делать? - person manzi; 19.02.2018
comment
Я заметил одну вещь: вызов System.out.println(dataSnapshot.toString()); он печатает все значения, я действительно не знаю, почему его нельзя отобразить как класс Java... - person manzi; 19.02.2018
comment
Нет, вы должны использовать геттеры и сеттеры. Должно быть: Ricetta ricetta = dataSnapshot.getValue(Ricetta.class), а затем RicettaG ricettaG = ricetta.getRicettaG(); - person Alex Mamo; 19.02.2018
comment
Извините, я не понял! Но в коде, который я написал, что я должен написать в getRicettaG() {} в Ricetta? Где в этом коде все атрибуты, добавленные в RicettaG, которых нет в Ricetta? Спасибо большое. - person manzi; 20.02.2018
comment
Да, но сначала вам нужно получить объект Ricetta из объекта dataSnapshot. Поскольку у вас есть поле типа класса RicettaG в классе Ricetta, вам нужно получить этот объект с помощью геттера, который должен быть: getRicettaG(). Таким образом, вы можете получить объект класса RicettaG: RicettaG ricettaG = ricetta.getRicettaG(); - person Alex Mamo; 20.02.2018
comment
Спасибо, сегодня попробую сделать! - person manzi; 22.02.2018
comment
Хорошо, и держи меня в курсе. - person Alex Mamo; 22.02.2018
comment
Это не работает, я действительно не знаю, почему. Теперь он заблокирован при выполнении Ricetta ricetta = dataSnapshot.getValue(Ricetta.class), он ничего не печатает в System.out, который я добавил после этого getValue. Я действительно не знаю. Что я могу сделать? Может быть, что-то не так с типами в базе данных по сравнению с моей Моделью? Я уже проверил это. Почему это не вызывает исключение или ошибку? Кажется, что заблокирован, действительно спасибо за вашу помощь и терпение - person manzi; 23.02.2018