如何在Android中使用firebase 9.2的自动值

epo*_*ool 6 java android firebase auto-value firebase-realtime-database

我想使用自动值火力9.2.0+.我有以下代码:

@AutoValue
public abstract class Office {

    public static Builder builder() {
        return new AutoValue_Office.Builder();
    }

    public abstract double latitud();
    public abstract double longitud();

    @AutoValue.Builder
    public static abstract class Builder {

        public abstract Builder latitud(double latitud);
        public abstract Builder longitud(double longitud);

        public abstract Office build();

    }

}
Run Code Online (Sandbox Code Playgroud)

但是当我打电话给Office office = childDataSnapshot.getValue(Office.class);我时,我收到了这个错误:

com.google.firebase.database.DatabaseException: No properties to serialize found on class com.example.app.model.Office
Run Code Online (Sandbox Code Playgroud)

有人知道我为什么会收到这个错误以及如何解决它?我读到firebase不再jackson用于json序列化.所以我不确定如何指定一种@JsonProperty("latitud")我用过的@PropertyName失败.

我也尝试重命名抽象方法public abstract double getLatitud();,然后错误是下一个:

java.lang.InstantiationException: Can't instantiate abstract class com.example.app.model.Office
Run Code Online (Sandbox Code Playgroud)

所以我不知道如何解决这个问题.

感谢hatboysamFrank van Puffelen,我终于可以通过下一个解决方案来解决这个问题了.

  1. 我创建了一个FirebaseUtil枚举,其中包含两个方法,用于基于hatboysam答案和Frank van Puffelen评论对Firebase的对象进行序列化和反序列化.
  2. 我创建了几个UserPhone类进行测试.
  3. 依赖关系:

    compile 'com.fasterxml.jackson.core:jackson-annotations:2.8.0'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.8.0'
    
    Run Code Online (Sandbox Code Playgroud)
  4. 用法示例:

    User user = FirebaseUtil.deserialize(dataSnapshot, User.class);
    Map<String, Object> map = FirebaseUtil.serialize(user);
    
    Run Code Online (Sandbox Code Playgroud)

Sam*_*ern 4

我不确定默认的 Firebase 数据映射器是否可以实现这一点,但有一个可能的解决方法。首先让我们解释一下您看到的错误:

com.google.firebase.database.DatabaseException:在类 com.example.app.model.Office 上找不到要序列化的属性

Firebase 映射器查找public字段或以getFoo/setFoo模式命名的字段。因此,在您的类上,映射器看不到任何属性。

java.lang.InstantiationException:无法实例化抽象类 com.example.app.model.Office

我认为这是一个你很难绕过的地方。为了使反序列化工作,您的类需要有一个公共的、无参数的构造函数,映射器可以通过反射(newInstance())调用该构造函数。据我所知,这不是 AutoValue 的工作原理。

但不要失去希望!。根据这个 github 问题,有一种方法可以使用@JsonCreator注释使 Jackson 和 AutoValue 兼容。因此,您需要同时使用 Jackson 和 Firebase来完成这里的工作。

序列化:

// Convert to a Map<String,Object> using Jackson and then pass that to Firebase
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.convertValue(office, Map.class);
databaseReference.setValue(map);
Run Code Online (Sandbox Code Playgroud)

反序列化:

// Use Firebase to convert to a Map<String,Object>
GenericTypeIndicator<Map<String,Object>> t = new GenericTypeIndicator<Map<String,Object>>() {};
Map<String,Object> map = dataSnap.getValue(t);

// Use Jackson to convert from a Map to an Office object
ObjectMapper mapper = new ObjectMapper();
Office pojo = mapper.convertValue(map, Office.class);
Run Code Online (Sandbox Code Playgroud)