firebase / firebase-admin-java

Firebase Admin Java SDK
https://firebase.google.com/docs/admin/setup
Apache License 2.0
545 stars 270 forks source link

Serializing java.time.LocalDate throws exception #86

Closed ghajba closed 5 years ago

ghajba commented 7 years ago

[REQUIRED] Step 2: Describe your environment

[REQUIRED] Step 3: Describe the problem

When I try to serialize a LocalDate I get the following exception.

com.google.firebase.database.DatabaseException: Found conflicting getters for name: getChronology
    at com.google.firebase.database.utilities.encoding.CustomClassMapper$BeanMapper.<init>(CustomClassMapper.java:476) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.loadOrCreateBeanMapperForClass(CustomClassMapper.java:324) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.serialize(CustomClassMapper.java:168) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.access$2(CustomClassMapper.java:117) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper$BeanMapper.serialize(CustomClassMapper.java:806) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.serialize(CustomClassMapper.java:169) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.access$2(CustomClassMapper.java:117) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper$BeanMapper.serialize(CustomClassMapper.java:806) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.serialize(CustomClassMapper.java:169) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.serialize(CustomClassMapper.java:143) ~[classes/:na]
    at com.google.firebase.database.utilities.encoding.CustomClassMapper.convertToPlainJavaTypes(CustomClassMapper.java:68) ~[classes/:na]
    at com.google.firebase.database.DatabaseReference.setValueInternal(DatabaseReference.java:321) ~[classes/:na]
    at com.google.firebase.database.DatabaseReference.setValue(DatabaseReference.java:229) ~[classes/:na]
    at com.google.firebase.database.DatabaseReference.setValueAsync(DatabaseReference.java:180) ~[classes/:na]

The cause is, that LocalDate overrides the java.time.chrono.ChronoLocalDate.getChronology() method which returns a java.time.chrono.Chronology. The override returns java.time.chrono.IsoChronology which is an implementation of the original return type.

Question: how can such overrides be addressed in the future that such classes (available in core Java or other libraries without access) can be serialized? If we can figure this out, I am happy to create a PR with the implementation.

google-oss-bot commented 7 years ago

Hey there! I couldn't figure out what this issue is about, so I've labeled it for a human to triage. Hang tight.

google-oss-bot commented 7 years ago

Hmmm this issue does not seem to follow the issue template. Make sure you provide all the required information.

hiranya911 commented 6 years ago

@schmidt-sebastian is this something we ought to support?

hiranya911 commented 5 years ago

We currently have no plans to support serialization of these date types. Please use java.util.Date in the meantime.

Related to #75

PlusLake commented 2 weeks ago

Here is 2024 now and JSR 310 (java.time) was shipped in Java 8 from 10 years ago. Users would be very happy if we don't need to deal with the conversion problem anymore.

Currently I copy paste this snippet to my project every time, just to transforming the data classes for using Firestore.

fun Any.toFirestoreObject() = this.javaClass.declaredFields.associate {
    it.isAccessible = true
    val transform = converters[it.type.kotlin] ?: { it }
    it.name to transform(it.get(this))
}

val converters = hashMapOf<KClass<*>, (Any) -> Any>(
    LocalDate::class to { Timestamp.valueOf((it as LocalDate).atStartOfDay()) },
    LocalDateTime::class to { Timestamp.valueOf(it as LocalDateTime) }
)