web-dev-qa-db-ja.com

getValue(Subclass.class)を使用してFirebaseのサブクラスを逆シリアル化する方法

Androidに新しいfirebase sdkを使用し、実際のデータベース機能を使用しています。getValue(simple.class)を使用すると、すべて問題ありません。ただし、クラスを解析する場合は、はサブクラスであり、マザークラスのすべての属性はnullであり、次のタイプのエラーが発生します。

クラスuk.edume.edumeapp.TestChildに名前のセッター/フィールドが見つかりません

public class TestChild  extends TestMother {

    private String childAttribute;

    public String getChildAttribute() {
        return childAttribute;
    }
}

public class TestMother {

    protected String motherAttribute;

    protected String getMotherAttribute() {
        return motherAttribute;
    }
}

この機能

snapshot.getValue(TestChild.class);

motherAttribute属性はnullであり、

クラスuk.edume.edumeapp.TestChildにmotherAttributeのセッター/フィールドが見つかりません

私が解析するJsonは次のとおりです。

{
  "childAttribute" : "attribute in child class",
  "motherAttribute" : "attribute in mother class"
}
14
drevlav

Firebaser here

これは、Android向けFirebase Database SDKの一部のバージョンでの既知のバグです。シリアライザー/デシリアライザーは、宣言されたクラスのプロパティ/フィールドのみを考慮します。

基本クラスから継承されたプロパティのシリアル化は、Firebase Database SDK for Androidのリリース9.0から9.6(iirc)にはありません。それ以来、バージョンに戻されました。

Workaround

それまでの間、Jackson(Firebase 2.x SDKが内部で使用)を使用して、継承モデルを機能させることができます。

更新:JSONからTestChild読み取りする方法のスニペットは次のとおりです。

_public class TestParent {
    protected String parentAttribute;

    public String getParentAttribute() {
        return parentAttribute;
    }
}
public class TestChild  extends TestParent {
    private String childAttribute;

    public String getChildAttribute() {
        return childAttribute;
    }
}
_

パブリックフィールド/ゲッターのみが考慮されるため、getParentAttribute()をパブリックにしたことに注意してください。その変更により、このJSON:

_{
  "childAttribute" : "child",
  "parentAttribute" : "parent"
}
_

次のコマンドで読み取り可能になります。

_ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);
_

GenericTypeIndicatorは少し奇妙ですが、幸いなことに、コピー/貼り付けできる魔法の呪文です。

18

これは明らかに最終的に リリース9.6 で修正されました。

派生クラスをDatabaseReference#setValue()に渡すと、スーパークラスからプロパティが正しく保存されない問題を修正しました。

6
JaviCasa

ために:

クラスuk.edume.edumeapp.TestChildにmotherAttributeのセッター/フィールドが見つかりません

testChildクラスのセッターを配置します。

 public class  TestMother {

     private String motherAttribute;

     public String getMotherAttribute() {
         return motherAttribute;
     }

     //set
     public void setMotherAttribute(String motherAttribute) {
         this.motherAttribute= motherAttribute;
     }
 }
2
Farzad

これを確認してください https://firebase.google.com/support/guides/firebase-Android

それは言う

"JSONにJavaクラスにない追加のプロパティがある場合、ログファイルに次の警告が表示されます。W/ ClassMapper:クラスにignoreThisPropertyのセッター/フィールドが見つかりませんcom.firebase.migrationguide.ChatMessage "

ブロッククォート

クラスに@IgnoreExtraPropertiesアノテーションを付けることで、この警告を取り除くことができます。 FirebaseDatabaseを2.xSDKの場合と同じように動作させ、不明なプロパティがある場合に例外をスローする場合は、クラスに@ThrowOnExtraPropertiesアノテーションを付けることができます。

ブロッククォート

0
Pb Studies