【问题标题】:Scala case classes with new firebase-server-sdk带有新的 firebase-server-sdk 的 Scala 案例类
【发布时间】:2016-07-22 19:11:39
【问题描述】:

firebase firebase-server-sdk (3.0.1) 的新服务器 SDK 是否支持 Scala 案例类反序列化?以前的 firebase java sdk 使用了 jackson,您可以将其插入 scala module 以支持案例类。不清楚是否可以用新的 SDK 做类似的事情?它使用 Gson 还是一些自定义类映射器?

最简单的例子:

case class Person(firstName: String, lastName: String, age: Int)

使用 Firebase 侦听器设置,例如:

var options = new FirebaseOptions.Builder()
  .setDatabaseUrl("https://<your firebase>.firebaseio.com")
  .setServiceAccount(new FileInputStream("firebase-auth.json"))
  .build()

FirebaseApp.initializeApp(options);

var ref = FirebaseDatabase.getInstance().getReference("somepath")
ref.addListenerForSingleValueEvent(new ValueEventListener {
  override def onDataChange(dataSnapshot: DataSnapshot): Unit = {
    println(dataSnapshot.getValue(classOf[Person]))
  }

  override def onCancelled(databaseError: DatabaseError): Unit = {
    println(databaseError.getMessage)
  }
})

这将在 getValue 调用 dataSnapshot.getValue(classOf[Person]) 上失败,但以下情况除外:

Exception in thread "FirebaseDatabaseEventTarget" com.google.firebase.database.DatabaseException: No properties to serialize found on class Person
    at com.google.firebase.database.utilities.encoding.CustomClassMapper$BeanMapper.<init>(CustomClassMapper.java:495)
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.loadOrCreateBeanMapperForClass(CustomClassMapper.java:285)
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:379)
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:187)
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:61)
    at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:181)
    at PetEventsNodeActorSpec$$anonfun$2$$anonfun$apply$mcV$sp$2$$anonfun$apply$mcV$sp$3$$anon$1.onDataChange(PetEventsNodeActorSpec.scala:290)
    at com.google.firebase.database.Query$1.onDataChange(Query.java:147)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:57)
    at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:45)
    at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:35)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我尝试向类添加注释,例如@BeanProperty,但随后得到:

Exception in thread "FirebaseDatabaseEventTarget" com.google.firebase.database.DatabaseException: Class Person is missing a constructor with no arguments

与其陷入为每个案例类添加注释或添加代码的兔子洞,还有什么想法可以让 scala 案例类与新的 firebase sdk 很好地配合使用?

【问题讨论】:

    标签: scala firebase firebase-realtime-database


    【解决方案1】:

    AFAIK,没有办法直接使用案例类。我最终创建了带有@BeanProperty 注释的普通类,然后将它们转换为案例类。原因

    Exception in thread "FirebaseDatabaseEventTarget" com.google.firebase.database.DatabaseException: Class Person is missing a constructor with no arguments
    

    是因为你的类构造函数必须是空的(即它不能接受任何参数):

    import scala.beans.BeanProperty
    
    case class Person(firstName: String, lastName: String, age: Int) {
      def toBean: PersonBean = {
        val person = new PersonBean()
        person.firstName = firstName
        person.lastName = lastName
        person.age = age
        person
      }
    }
    
    class PersonBean() {
      @BeanProperty var firstName: String = ""
      @BeanProperty var lastName: String = ""
      @BeanProperty var age: Int = 0
      def toCase: Person = Person(firstName, lastName, age)
    }
    
    var ref = FirebaseDatabase.getInstance().getReference("somepath")
    ref.addListenerForSingleValueEvent(new ValueEventListener {
      override def onDataChange(dataSnapshot: DataSnapshot): Unit = {
        val record = dataSnapshot.getValue(classOf[PersonBean])
        val person = if (record != null) record.toCase else null
      }
    
      override def onCancelled(databaseError: DatabaseError): Unit = {
        println(databaseError.getMessage)
      }
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-29
      • 2019-10-31
      • 1970-01-01
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      相关资源
      最近更新 更多