使用新的firebase-server-sdk的Scala案例类 [英] Scala case classes with new firebase-server-sdk

查看:55
本文介绍了使用新的firebase-server-sdk的Scala案例类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否为firebase firebase-server-sdk 的新服务器SDK (3.0.1)是否支持Scala案例类反序列化?以前的Firebase Java SDK使用jackson,您可以使用 scala模块来支持案例类.目前尚不清楚是否可以使用新的SDK做类似的事情?它使用Gson还是某些自定义类映射器?

Does the new server SDK for firebase firebase-server-sdk (3.0.1) support Scala case class deserialization? The previous firebase java sdk used jackson which you could bolt in a scala module to support case classes. It's unclear if its possible to do something similar with the new SDK? Does it use Gson or some custom class mapper?

在最简单的示例中:

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

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

With a Firebase listener setup such as:

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])上失败,除了:

This will fail on the getValue call dataSnapshot.getValue(classOf[Person]) with the exception:

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之类的类中,但随后得到:

I've tried adding annotations to the class such as @BeanProperty but then get:

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

关于让scala案例类与新的firebase sdk完美配合的任何想法,而不是费力地为每个案例类添加注释或添加代码?

Rather than go down the rabbit hole of annotating or adding code to every case class, any ideas on getting scala case classes to play nicely with the new firebase sdk?

推荐答案

AFAIK,无法直接使用案例类.我最终用@BeanProperty注释创建了普通类,然后将它们转换为case类.

AFAIK, there isn't a way to use a case class directly. I ended up creating plain classes with @BeanProperty annotations and then converting them to case classes. The reason for

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

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

is because your class constructor must be nullary (i.e. it cannot take any 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)
  }
})

这篇关于使用新的firebase-server-sdk的Scala案例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆