Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ implementation 'com.google.cloud:google-cloud-firestore'
If you are using Gradle without BOM, add this to your dependencies:

```Groovy
implementation 'com.google.cloud:google-cloud-firestore:3.17.0'
implementation 'com.google.cloud:google-cloud-firestore:3.17.1'
```

If you are using SBT, add this to your dependencies:

```Scala
libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.17.0"
libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.17.1"
```
<!-- {x-version-update-end} -->

Expand Down Expand Up @@ -222,7 +222,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-firestore/java11.html
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-firestore.svg
[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-firestore/3.17.0
[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-firestore/3.17.1
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -175,6 +176,9 @@ private static <T> Object serialize(T o, ErrorPath path) {
|| o instanceof FieldValue
|| o instanceof Value) {
return o;
} else if (o instanceof Instant) {
Instant instant = (Instant) o;
return Timestamp.ofTimeSecondsAndNanos(instant.getEpochSecond(), instant.getNano());
} else {
Class<T> clazz = (Class<T>) o.getClass();
BeanMapper<T> mapper = loadOrCreateBeanMapperForClass(clazz);
Expand Down Expand Up @@ -233,6 +237,8 @@ private static <T> T deserializeToClass(Object o, Class<T> clazz, DeserializeCon
return (T) convertDate(o, context);
} else if (Timestamp.class.isAssignableFrom(clazz)) {
return (T) convertTimestamp(o, context);
} else if (Instant.class.isAssignableFrom(clazz)) {
return (T) convertInstant(o, context);
} else if (Blob.class.isAssignableFrom(clazz)) {
return (T) convertBlob(o, context);
} else if (GeoPoint.class.isAssignableFrom(clazz)) {
Expand Down Expand Up @@ -557,6 +563,19 @@ private static Timestamp convertTimestamp(Object o, DeserializeContext context)
}
}

private static Instant convertInstant(Object o, DeserializeContext context) {
if (o instanceof Timestamp) {
Timestamp timestamp = (Timestamp) o;
return Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos());
} else if (o instanceof Date) {
return Instant.ofEpochMilli(((Date) o).getTime());
} else {
throw deserializeError(
context.errorPath,
"Failed to convert value of type " + o.getClass().getName() + " to Instant");
}
}

private static Blob convertBlob(Object o, DeserializeContext context) {
if (o instanceof Blob) {
return (Blob) o;
Expand Down Expand Up @@ -976,13 +995,13 @@ Map<String, Object> serialize(T object, ErrorPath path) {
private void applyFieldAnnotations(Field field) {
if (field.isAnnotationPresent(ServerTimestamp.class)) {
Class<?> fieldType = field.getType();
if (fieldType != Date.class && fieldType != Timestamp.class) {
if (fieldType != Date.class && fieldType != Timestamp.class && fieldType != Instant.class) {
throw new IllegalArgumentException(
"Field "
+ field.getName()
+ " is annotated with @ServerTimestamp but is "
+ fieldType
+ " instead of Date or Timestamp.");
+ " instead of Date, Timestamp, or Instant.");
}
serverTimestamps.add(propertyName(field));
}
Expand All @@ -997,13 +1016,15 @@ private void applyFieldAnnotations(Field field) {
private void applyGetterAnnotations(Method method) {
if (method.isAnnotationPresent(ServerTimestamp.class)) {
Class<?> returnType = method.getReturnType();
if (returnType != Date.class && returnType != Timestamp.class) {
if (returnType != Date.class
&& returnType != Timestamp.class
&& returnType != Instant.class) {
throw new IllegalArgumentException(
"Method "
+ method.getName()
+ " is annotated with @ServerTimestamp but returns "
+ returnType
+ " instead of Date or Timestamp.");
+ " instead of Date, Timestamp, or Instant.");
}
serverTimestamps.add(propertyName(method));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ public void extractFieldMaskFromMerge() throws Exception {
"second.foo",
"second.geoPointValue",
"second.infValue",
"second.instantValue",
"second.longValue",
"second.nanValue",
"second.negInfValue",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -148,6 +149,7 @@ public final class LocalFirestoreHelper {

public static final Date DATE;
public static final Timestamp TIMESTAMP;
public static final Instant INSTANT;
public static final GeoPoint GEO_POINT;
public static final Blob BLOB;
public static final FooList<SingleField> FOO_LIST = new FooList<>();
Expand Down Expand Up @@ -942,6 +944,7 @@ public static class AllSupportedTypes {
public SingleField objectValue = new SingleField();
public Date dateValue = DATE;
public Timestamp timestampValue = TIMESTAMP;
public Instant instantValue = INSTANT;
public List<String> arrayValue = ImmutableList.of("foo");
public String nullValue = null;
public Blob bytesValue = BLOB;
Expand All @@ -968,6 +971,7 @@ public boolean equals(Object o) {
&& Objects.equals(objectValue, that.objectValue)
&& Objects.equals(dateValue, that.dateValue)
&& Objects.equals(timestampValue, that.timestampValue)
&& Objects.equals(instantValue, that.instantValue)
&& Objects.equals(arrayValue, that.arrayValue)
&& Objects.equals(nullValue, that.nullValue)
&& Objects.equals(bytesValue, that.bytesValue)
Expand All @@ -989,6 +993,10 @@ public boolean equals(Object o) {
Timestamp.ofTimeSecondsAndNanos(
TimeUnit.MILLISECONDS.toSeconds(DATE.getTime()),
123000); // Firestore truncates to microsecond precision.
INSTANT =
Instant.ofEpochSecond(
TimeUnit.MILLISECONDS.toSeconds(DATE.getTime()),
123000); // Firestore truncates to microsecond precision.
GEO_POINT = new GeoPoint(50.1430847, -122.9477780);
BLOB = Blob.fromBytes(new byte[] {1, 2, 3});
SINGLE_FLOAT_MAP = map("float", 0.1F);
Expand Down Expand Up @@ -1083,6 +1091,7 @@ public boolean equals(Object o) {
ALL_SUPPORTED_TYPES_MAP.put("objectValue", map("foo", (Object) "bar"));
ALL_SUPPORTED_TYPES_MAP.put("dateValue", Timestamp.of(DATE));
ALL_SUPPORTED_TYPES_MAP.put("timestampValue", TIMESTAMP);
ALL_SUPPORTED_TYPES_MAP.put("instantValue", TIMESTAMP);
ALL_SUPPORTED_TYPES_MAP.put("arrayValue", ImmutableList.of("foo"));
ALL_SUPPORTED_TYPES_MAP.put("nullValue", null);
ALL_SUPPORTED_TYPES_MAP.put("bytesValue", BLOB);
Expand Down Expand Up @@ -1119,6 +1128,14 @@ public boolean equals(Object o) {
.setSeconds(479978400)
.setNanos(123000)) // Timestamps supports microsecond precision.
.build())
.put(
"instantValue",
Value.newBuilder()
.setTimestampValue(
com.google.protobuf.Timestamp.newBuilder()
.setSeconds(479978400)
.setNanos(123000)) // Instants supports microsecond precision.
.build())
.put(
"arrayValue",
Value.newBuilder()
Expand Down