2016-06-05 6 views
1

У меня есть данные в моей базе данных firebase, все работает нормально, пока я не попытаюсь де-сериализовать данные.Firebase с царством. Де-сериализация класса POJO

Ошибка: аргумент 1 имеет тип io.realm.RealmList, получил java.util.ArrayList

Вот мой код:

DatabaseReference root = FirebaseDatabase.getInstance(). 
       getReferenceFromUrl("https://swing-8792d.firebaseio.com/playlist"); 
     Query playlistQuery = root.orderByKey().equalTo(key); 
     playlistQuery.addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       for (DataSnapshot child : dataSnapshot.getChildren()) { 

        Log.d("Child", child + ""); 

        Playlist receivedPlaylist = child.getValue(Playlist.class); 
        Playlist playlist = new Playlist(); 

        playlist.setCreatedBy(receivedPlaylist.getCreatedBy()); 
        playlist.setName(receivedPlaylist.getName()); 
        playlist.setMyMap(receivedPlaylist.getMyMap()); 
        playlist.setQrKey(receivedPlaylist.getQrKey()); 
        playlist.setCount(receivedPlaylist.getCount()); 
        playlist.setId(receivedPlaylist.getId()); 
        playlist.setTracks(receivedPlaylist.getTracks()); 
        mPlaylist.add(playlist); 
} 

Это мой POJO класс:

@RealmClass 
public class Playlist extends RealmObject { 

String name; 
Long id; 
RealmList<Track> tracks; 
Integer count; 
String createdBy; 
RealmList<UserMap> myMap; 
String qrKey; 

public RealmList<UserMap> getMyMap() { 
    return myMap; 
} 

public void setMyMap(RealmList<UserMap> myMap) { 
    this.myMap = myMap; 
} 

public Playlist(){} 



public String getQrKey() { 
    return qrKey; 
} 

public void setQrKey(String qrKey) { 
    this.qrKey = qrKey; 
} 

public String getCreatedBy() { 
    return createdBy; 
} 

public void setCreatedBy(String createdBy) { 
    this.createdBy = createdBy; 
} 


public RealmList<Track> getTracks() { 
    return tracks; 
} 

public void setTracks(RealmList<Track> tracks) { 
    this.tracks = tracks; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public Long getId() { 
    return id; 
} 

public void setId(Long id) { 
    this.id = id; 
} 

public Integer getCount() { 
    return count; 
} 

public void setCount(Integer count) { 
    this.count = count; 
} 

}

Если я попытаюсь де-сериализовать с помощью Norma l Класс POJO (т. е. удаление Realm) работает отлично.

ответ

4

Firebase не будет работать с классами, у которых нет default конструктор или частные переменные. I.e нет публичного getter/setter.

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

Псевдокода

class SimplePojoPlaylist { 
    public String variable; 
} 

class Playlist extends RealmObject { 
    public String variable; 
} 

Тогда первый отливает в SimplePojoPlaylist

for (DataSnapshot child : dataSnapshot.getChildren()) { 
     SimplePojoPlaylist receivedPlaylist = child.getValue(SimplePojoPlaylist.class); 
     Playlist playList = new Playlist(); 
     playList.variable = receivedPlaylist.variable; 
    } 
+0

Я удаляю свои геттеры и сеттеры? –

+0

вы можете сохранить их. Я не использовал их, чтобы держать ответ коротким. – Shubhank

+0

Одна из проблем заключается в том, что в моем плейлисте есть RealmList, но у SimplePojoList будет Arraylist, как я могу справиться с этим –

1

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

Check this link from the docs:

Кроме того, это хорошая практика, чтобы сделать ваши объекты неизменные, чтобы избежать нежелательного доступа и/или модификации.

Создание пустого объекта с нуля, а затем вызов методов setter для определения его состояния не очень хороший шаблон, поскольку он может создать ситуацию, когда к объекту обращаются до того, когда его состояние «сломано».

Если вам нужно создать объект, который является гибким, имеет несколько обязательных полей и некоторые необязательные, подумайте об использовании шаблона Builder, хотя для этого вам придется перепроектировать вашу модель.

wikipedia - Builder

Если вам не нужны/хотят использовать строитель, мой совет:

1) Сделать пустой конструктор приватным и создать еще один публичный, требующий все поля.

2) Измените свое поле треков на тип «Список». Затем, если вам нужен объект, чтобы вернуть RealmList, создайте другой метод getter, такой как tracksAsRealmList(), который выведет RealmList из списка участников и вернет его.

3) Убедитесь, что модель «Track» имеет пустой частный конструктор, общедоступный со всеми его параметрами и что все его поля поддерживаются десериализацией firebase.

4) Если строго необходимо, сделайте свои поля объектов частными и установите его значение с помощью метода сеттера.

Надеюсь, это вам поможет.

Смежные вопросы