Skip to content

Commit 57e18a9

Browse files
committed
fix: add support for deserialize a class extending ArrayList
1 parent 556b7b9 commit 57e18a9

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

google-cloud-firestore/src/main/java/com/google/cloud/firestore/CustomClassMapper.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,18 @@ private static <T> T deserializeToParameterizedType(
266266
Type genericType = type.getActualTypeArguments()[0];
267267
if (o instanceof List) {
268268
List<Object> list = (List<Object>) o;
269-
List<Object> result = new ArrayList<>(list.size());
269+
List<Object> result = null;
270+
try {
271+
result =
272+
(rawType == List.class)
273+
? new ArrayList<>(list.size())
274+
: (List<Object>) rawType.getDeclaredConstructor().newInstance();
275+
} catch (InstantiationException
276+
| IllegalAccessException
277+
| NoSuchMethodException
278+
| InvocationTargetException e) {
279+
throw new RuntimeException(e);
280+
}
270281
for (int i = 0; i < list.size(); i++) {
271282
result.add(
272283
deserializeToType(

google-cloud-firestore/src/test/java/com/google/cloud/firestore/DocumentReferenceTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static com.google.cloud.firestore.LocalFirestoreHelper.DOCUMENT_NAME;
2525
import static com.google.cloud.firestore.LocalFirestoreHelper.DOCUMENT_PATH;
2626
import static com.google.cloud.firestore.LocalFirestoreHelper.FIELD_TRANSFORM_COMMIT_RESPONSE;
27+
import static com.google.cloud.firestore.LocalFirestoreHelper.FOO_LIST;
2728
import static com.google.cloud.firestore.LocalFirestoreHelper.GEO_POINT;
2829
import static com.google.cloud.firestore.LocalFirestoreHelper.NESTED_CLASS_OBJECT;
2930
import static com.google.cloud.firestore.LocalFirestoreHelper.SERVER_TIMESTAMP_PROTO;
@@ -69,10 +70,13 @@
6970
import com.google.cloud.firestore.LocalFirestoreHelper.InvalidPOJO;
7071
import com.google.cloud.firestore.spi.v1.FirestoreRpc;
7172
import com.google.common.collect.ImmutableList;
73+
import com.google.common.collect.ImmutableMap;
74+
import com.google.firestore.v1.ArrayValue;
7275
import com.google.firestore.v1.BatchGetDocumentsRequest;
7376
import com.google.firestore.v1.BatchGetDocumentsResponse;
7477
import com.google.firestore.v1.CommitRequest;
7578
import com.google.firestore.v1.CommitResponse;
79+
import com.google.firestore.v1.MapValue;
7680
import com.google.firestore.v1.Value;
7781
import java.math.BigInteger;
7882
import java.util.ArrayList;
@@ -1073,4 +1077,33 @@ public void deleteNestedFieldUsingFieldPath() throws Exception {
10731077
Collections.<String, Value>emptyMap(), Collections.singletonList("`a.b`.`c.d`")));
10741078
assertEquals(expectedCommit, commitCapture.getValue());
10751079
}
1080+
1081+
@Test
1082+
public void deserializeCustomList() throws ExecutionException, InterruptedException {
1083+
ImmutableMap CUSTOM_LIST_PROTO =
1084+
ImmutableMap.<String, Value>builder()
1085+
.put(
1086+
"fooList",
1087+
Value.newBuilder()
1088+
.setArrayValue(
1089+
ArrayValue.newBuilder()
1090+
.addValues(
1091+
Value.newBuilder()
1092+
.setMapValue(
1093+
MapValue.newBuilder().putAllFields(SINGLE_FIELD_PROTO))
1094+
.build()))
1095+
.build())
1096+
.build();
1097+
doAnswer(getAllResponse(CUSTOM_LIST_PROTO))
1098+
.when(firestoreMock)
1099+
.streamRequest(
1100+
getAllCapture.capture(),
1101+
streamObserverCapture.capture(),
1102+
Matchers.<ServerStreamingCallable>any());
1103+
DocumentSnapshot snapshot = documentReference.get().get();
1104+
LocalFirestoreHelper.CustomList customList =
1105+
snapshot.toObject(LocalFirestoreHelper.CustomList.class);
1106+
1107+
assertEquals(FOO_LIST, customList.fooList);
1108+
}
10761109
}

google-cloud-firestore/src/test/java/com/google/cloud/firestore/LocalFirestoreHelper.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ public final class LocalFirestoreHelper {
143143
public static final Timestamp TIMESTAMP;
144144
public static final GeoPoint GEO_POINT;
145145
public static final Blob BLOB;
146+
public static final FooList<SingleField> FOO_LIST = new FooList<>();
146147

147148
public static final Precondition UPDATE_PRECONDITION;
148149

@@ -165,6 +166,18 @@ public boolean equals(Object o) {
165166
}
166167
}
167168

169+
public static class FooList<E> extends ArrayList<SingleField> {
170+
public FooList() {
171+
super();
172+
}
173+
}
174+
175+
public static class CustomList {
176+
public CustomList() {}
177+
178+
public FooList<SingleField> fooList;
179+
}
180+
168181
public static class NestedClass {
169182
public SingleField first = new SingleField();
170183
public AllSupportedTypes second = new AllSupportedTypes();
@@ -773,6 +786,7 @@ public boolean equals(Object o) {
773786
SINGLE_FIELD_MAP = map("foo", (Object) "bar");
774787
SINGLE_FILED_MAP_WITH_DOT = map("c.d", (Object) "bar");
775788
SINGLE_FIELD_OBJECT = new SingleField();
789+
FOO_LIST.add(SINGLE_FIELD_OBJECT);
776790
SINGLE_FIELD_PROTO = map("foo", Value.newBuilder().setStringValue("bar").build());
777791
UPDATED_POJO_PROTO =
778792
map(

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.google.cloud.firestore.it;
1818

19+
import static com.google.cloud.firestore.LocalFirestoreHelper.FOO_LIST;
1920
import static com.google.cloud.firestore.LocalFirestoreHelper.UPDATE_SINGLE_FIELD_OBJECT;
2021
import static com.google.cloud.firestore.LocalFirestoreHelper.map;
2122
import static com.google.common.truth.Truth.assertThat;
@@ -1402,6 +1403,18 @@ public Void updateCallback(Transaction transaction) throws Exception {
14021403
}
14031404
}
14041405

1406+
@Test
1407+
public void deserializeCustomList() throws Exception {
1408+
LocalFirestoreHelper.CustomList customList = new LocalFirestoreHelper.CustomList();
1409+
customList.fooList = FOO_LIST;
1410+
DocumentReference documentReference = randomColl.document("doc1");
1411+
documentReference.set(customList).get();
1412+
DocumentSnapshot documentSnapshots = documentReference.get().get();
1413+
LocalFirestoreHelper.CustomList targetCustomList =
1414+
documentSnapshots.toObject(LocalFirestoreHelper.CustomList.class);
1415+
assertEquals(FOO_LIST, targetCustomList.fooList);
1416+
}
1417+
14051418
/** Wrapper around ApiStreamObserver that returns the results in a list. */
14061419
private static class StreamConsumer<T> implements ApiStreamObserver<T> {
14071420
SettableApiFuture<List<T>> done = SettableApiFuture.create();

0 commit comments

Comments
 (0)