Skip to content

Commit bad000d

Browse files
committed
Add support for kotlinx.datetime.Instant.
Add tests.
1 parent 1fde57d commit bad000d

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

firebase-firestore/firebase-firestore.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ dependencies {
142142
implementation libs.grpc.stub
143143
implementation libs.kotlin.stdlib
144144
implementation libs.kotlinx.coroutines.core
145+
implementation libs.kotlinx.datetime
145146

146147
compileOnly libs.autovalue.annotations
147148
compileOnly libs.javax.annotation.jsr250

firebase-firestore/src/main/java/com/google/firebase/firestore/util/CustomClassMapper.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ private static <T> Object serialize(T o, ErrorPath path) {
183183
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && o instanceof Instant) {
184184
Instant instant = (Instant) o;
185185
return new Timestamp(instant.getEpochSecond(), instant.getNano());
186+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
187+
&& o instanceof kotlinx.datetime.Instant) {
188+
kotlinx.datetime.Instant instant = (kotlinx.datetime.Instant) o;
189+
return new Timestamp(instant.getEpochSeconds(), instant.getNanosecondsOfSecond());
186190
} else if (o instanceof Uri || o instanceof URI || o instanceof URL) {
187191
return o.toString();
188192
} else {
@@ -246,6 +250,9 @@ private static <T> T deserializeToClass(Object o, Class<T> clazz, DeserializeCon
246250
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
247251
&& Instant.class.isAssignableFrom(clazz)) {
248252
return (T) convertInstant(o, context);
253+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
254+
&& kotlinx.datetime.Instant.class.isAssignableFrom(clazz)) {
255+
return (T) new kotlinx.datetime.Instant(convertInstant(o, context));
249256
} else if (Blob.class.isAssignableFrom(clazz)) {
250257
return (T) convertBlob(o, context);
251258
} else if (GeoPoint.class.isAssignableFrom(clazz)) {
@@ -958,7 +965,8 @@ private void applyFieldAnnotations(Field field) {
958965
Class<?> fieldType = field.getType();
959966
if (fieldType != Date.class
960967
&& fieldType != Timestamp.class
961-
&& !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && fieldType == Instant.class)) {
968+
&& !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
969+
&& (fieldType == Instant.class || fieldType == kotlinx.datetime.Instant.class))) {
962970
throw new IllegalArgumentException(
963971
"Field "
964972
+ field.getName()
@@ -981,7 +989,8 @@ private void applyGetterAnnotations(Method method) {
981989
Class<?> returnType = method.getReturnType();
982990
if (returnType != Date.class
983991
&& returnType != Timestamp.class
984-
&& !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && returnType == Instant.class)) {
992+
&& !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
993+
&& (returnType == Instant.class || returnType == kotlinx.datetime.Instant.class))) {
985994
throw new IllegalArgumentException(
986995
"Method "
987996
+ method.getName()

firebase-firestore/src/test/java/com/google/firebase/firestore/util/MapperTest.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
import static org.junit.Assert.fail;
2323

2424
import androidx.annotation.Nullable;
25+
import com.google.firebase.Timestamp;
2526
import com.google.firebase.firestore.DocumentId;
2627
import com.google.firebase.firestore.DocumentReference;
2728
import com.google.firebase.firestore.Exclude;
2829
import com.google.firebase.firestore.PropertyName;
2930
import com.google.firebase.firestore.TestUtil;
3031
import com.google.firebase.firestore.ThrowOnExtraProperties;
3132
import java.io.Serializable;
33+
import java.time.Instant;
3234
import java.util.ArrayList;
3335
import java.util.Arrays;
3436
import java.util.Collection;
@@ -37,6 +39,7 @@
3739
import java.util.HashMap;
3840
import java.util.List;
3941
import java.util.Map;
42+
import java.util.Objects;
4043
import java.util.Set;
4144
import org.junit.Test;
4245
import org.robolectric.annotation.Config;
@@ -95,6 +98,44 @@ public boolean isValue() {
9598
}
9699
}
97100

101+
private static class TimeBean {
102+
public Timestamp timestamp;
103+
public Date date;
104+
public Instant instant;
105+
public kotlinx.datetime.Instant instantKt;
106+
107+
@Override
108+
public boolean equals(Object o) {
109+
if (o == null || getClass() != o.getClass()) {
110+
return false;
111+
}
112+
TimeBean timeBean = (TimeBean) o;
113+
return Objects.equals(timestamp, timeBean.timestamp)
114+
&& Objects.equals(date, timeBean.date)
115+
&& Objects.equals(instant, timeBean.instant)
116+
&& Objects.equals(instantKt, timeBean.instantKt);
117+
}
118+
119+
@Override
120+
public int hashCode() {
121+
return Objects.hash(timestamp, date, instant, instantKt);
122+
}
123+
124+
@Override
125+
public String toString() {
126+
return "TimeBean{"
127+
+ "_date="
128+
+ date
129+
+ ", _timestamp="
130+
+ timestamp
131+
+ ", _instant="
132+
+ instant
133+
+ ", _instantKt="
134+
+ instantKt
135+
+ '}';
136+
}
137+
}
138+
98139
private static class ShortBean {
99140
private short value;
100141

@@ -1476,6 +1517,48 @@ public void serializeBooleanBean() {
14761517
assertJson("{'value': true}", serialize(bean));
14771518
}
14781519

1520+
@Test
1521+
public void serializeTimeBean() {
1522+
TimeBean bean = new TimeBean();
1523+
bean.instant = Instant.ofEpochSecond(1234, 5678);
1524+
bean.timestamp = new Timestamp(bean.instant);
1525+
bean.date = new Date(1234);
1526+
bean.instantKt = new kotlinx.datetime.Instant(bean.instant);
1527+
assertEquals(
1528+
Map.of(
1529+
"timestamp",
1530+
bean.timestamp,
1531+
"date",
1532+
bean.date,
1533+
"instant",
1534+
bean.timestamp,
1535+
"instantKt",
1536+
bean.timestamp),
1537+
serialize(bean));
1538+
}
1539+
1540+
@Test
1541+
public void deserializeTimeBean() {
1542+
TimeBean bean = new TimeBean();
1543+
bean.instant = Instant.ofEpochSecond(1234, 5678);
1544+
bean.timestamp = new Timestamp(bean.instant);
1545+
bean.date = new Date(1234);
1546+
bean.instantKt = new kotlinx.datetime.Instant(bean.instant);
1547+
assertEquals(
1548+
bean,
1549+
convertToCustomClass(
1550+
Map.of(
1551+
"timestamp",
1552+
bean.timestamp,
1553+
"date",
1554+
bean.date,
1555+
"instant",
1556+
bean.timestamp,
1557+
"instantKt",
1558+
bean.timestamp),
1559+
TimeBean.class));
1560+
}
1561+
14791562
@Test
14801563
public void serializeFloatBean() {
14811564
FloatBean bean = new FloatBean();

0 commit comments

Comments
 (0)