Смерть от (Тысячи) заклинаний

Когда все является объектом, ничто не является.

Слушатели событий Firebase - это Magic. По мере обновления данных в Firebase уведомления отправляются в ваше приложение Android в виде удобных данных карты в кодировке JSON. Хотя это хорошо, когда вся сантехника закрыта, если вы не будете осторожны при использовании этой карты, ваш код может вызвать кошмары при обслуживании.

Карта - это ловушка

Информация, которую вы получаете в onDataChanged, находится в форме объекта Map в кодировке JSON. Конечно, вы захотите извлечь информацию из этой карты, а это означает, что вы, скорее всего, захотите привести объекты из их типа данных карты в какой-либо пригодный для использования объект.

Рассмотрим этот типичный пример ниже. Хотя это может показаться простым, не верьте этому. Это ловушка.

// WARNING: This is an anti-pattern, copy and paste at your own risk
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
   Object data = dataSnapshot.getValue();
   Map<String, Object> map = (Map<String, Object>)data;
   String name = (String) map.get("name");
   String location = (String) map.get("location");
}

Проблема в том, что использование объекта карты приводит к большому количеству операций приведения объекта.

Этот тип кода-паттерна позволяет решить множество проблем с обслуживанием.

К счастью, в Firebase есть удобный процесс, который позволяет избежать обеих этих проблем. Он называется файлом .class.

Десериализовать с помощью .class

Шаблон .class позволяет вам определять классы, которые представляют вашу структуру данных, чтобы вы могли быстрее извлекать их во время процесса десериализации.

Чтобы использовать это, нам сначала нужно создать определение нашего класса для нашего Person.

public class Person {
  String name;
  String location;
  // getters required for deserialization
  public String getName() { return name; }
  public String getLocation() { return location; }
}

Когда вы передаете DataSnapshot в onDataChange, вы можете использовать метод .getValue (), передавая .class человека. Когда вы это сделаете, Firebase будет использовать отражение для десериализации содержимого JSON и заполнения свойств созданного экземпляра объекта Person от вашего имени.

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
  Person person = dataSnapshot.getValue(Person.class);
}

Этот однострочник работает, потому что Firebase SDK поставляется вместе с Jackson для десериализации.

В результате больше не будет многострочного преобразования типов, и вам не придется беспокоиться об обработке ClassCastException. Если свойство не существует в значении DataSnapshot, оно будет инициализировано значением по умолчанию.

Не делай этого в одиночку

Когда дело доходит до десериализации данных, не утомляйте себя бесконечной цепочкой приведений типов. Пусть Firebase сделает за вас тяжелую работу.