From 7c5aa770bb47d1441aa85c6c9e8f9582a9439318 Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Wed, 16 Jan 2019 17:51:41 -0800 Subject: [PATCH] Firestore: change timestampsInSnapshots default to true. BREAKING CHANGE: The `areTimestampsInSnapshotsEnabled()` setting is now enabled by default so timestamp fields read from a `DocumentSnapshot` will be returned as `Timestamp` objects instead of `Date`. Any code expecting to receive a `Date` object must be updated. --- .../google/cloud/firestore/FirestoreImpl.java | 28 ---------------- .../cloud/firestore/FirestoreOptions.java | 32 +++++++++---------- .../firestore/CollectionReferenceTest.java | 5 +-- .../cloud/firestore/ConformanceTest.java | 6 +--- .../firestore/DocumentReferenceTest.java | 5 +-- .../google/cloud/firestore/FirestoreTest.java | 5 +-- .../com/google/cloud/firestore/QueryTest.java | 5 +-- .../cloud/firestore/TransactionTest.java | 6 +--- .../com/google/cloud/firestore/WatchTest.java | 6 +--- .../cloud/firestore/WriteBatchTest.java | 5 +-- .../cloud/firestore/it/ITSystemTest.java | 3 +- 11 files changed, 25 insertions(+), 81 deletions(-) diff --git a/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java b/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java index 54d479fbda22..568ee6f0b87b 100644 --- a/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java +++ b/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java @@ -85,34 +85,6 @@ class FirestoreImpl implements Firestore { + "Please explicitly set your Project ID in FirestoreOptions."); this.databasePath = ResourcePath.create(DatabaseRootName.of(options.getProjectId(), options.getDatabaseId())); - - if (!options.areTimestampsInSnapshotsEnabled()) { - LOGGER.warning( - "The behavior for java.util.Date objects stored in Firestore is going to change " - + "AND YOUR APP MAY BREAK.\n" - + "To hide this warning and ensure your app does not break, you need to add " - + "the following code to your app before calling any other Cloud Firestore " - + "methods:\n" - + "\n" - + "FirestoreOptions options = \n" - + " FirestoreOptions.newBuilder().setTimestampsInSnapshotsEnabled(true).build();\n" - + "Firestore firestore = options.getService();\n" - + "\n" - + "With this change, timestamps stored in Cloud Firestore will be read back as " - + "com.google.cloud.Timestamp objects instead of as system java.util.Date " - + "objects. So you will also need to update code expecting a java.util.Date to " - + "instead expect a Timestamp. For example:\n" - + "\n" - + "// Old:\n" - + "java.util.Date date = (java.util.Date) snapshot.get(\"created_at\");\n" - + "// New:\n" - + "Timestamp timestamp = (Timestamp) snapshot.get(\"created_at\");\n" - + "java.util.Date date = timestamp.toDate();\n" - + "\n" - + "Please audit all existing usages of java.util.Date when you enable the new " - + "behavior. In a future release, the behavior will be changed to the new " - + "behavior, so if you do not follow these steps, YOUR APP MAY BREAK."); - } } /** Creates a pseudo-random 20-character ID that can be used for Firestore documents. */ diff --git a/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreOptions.java b/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreOptions.java index 7eb23074a73b..7bee4c05b871 100644 --- a/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreOptions.java +++ b/google-cloud-clients/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreOptions.java @@ -44,7 +44,7 @@ public final class FirestoreOptions extends ServiceOptionsCurrently, Firestore returns timestamp fields as {@link java.util.Date} but {@link - * java.util.Date Date} only supports millisecond precision, which leads to truncation and - * causes unexpected behavior when using a timestamp from a snapshot as a part of a subsequent - * query. + *

Previously, Firestore returned timestamp fields as {@link java.util.Date} but {@link + * java.util.Date} only supports millisecond precision, which leads to truncation and causes + * unexpected behavior when using a timestamp from a snapshot as a part of a subsequent query. * - *

Setting {@code setTimestampsInSnapshotsEnabled(true)} will cause Firestore to return - * {@link com.google.cloud.Timestamp Timestamp} values instead of {@link java.util.Date Date}, - * avoiding this kind of problem. To make this work you must also change any code that uses - * {@link java.util.Date Date} to use {@link com.google.cloud.Timestamp Timestamp} instead. + *

So now Firestore returns {@link com.google.cloud.Timestamp Timestamp} values instead of + * {@link java.util.Date}, avoiding this kind of problem. * - *

NOTE: in the future {@link FirestoreOptions#areTimestampsInSnapshotsEnabled} will default - * to true and this option will be removed so you should change your code to use Timestamp now - * and opt-in to this new behavior as soon as you can. + *

To opt into the old behavior of returning {@link java.util.Date Dates}, you can + * temporarily set {@link FirestoreOptions#areTimestampsInSnapshotsEnabled} to false. * - * @return A settings object on which the return type for timestamp fields is configured as - * specified by the given {@code value}. + * @deprecated This setting now defaults to true and will be removed in a future release. If you + * are already setting it to true, just remove the setting. If you are setting it to false, + * you should update your code to expect {@link com.google.cloud.Timestamp Timestamps} + * instead of {@link java.util.Date Dates} and then remove the setting. */ + @Deprecated @Nonnull public Builder setTimestampsInSnapshotsEnabled(boolean value) { this.timestampsInSnapshotsEnabled = value; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/CollectionReferenceTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/CollectionReferenceTest.java index e119bbead18c..47934c4d2890 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/CollectionReferenceTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/CollectionReferenceTest.java @@ -43,10 +43,7 @@ public class CollectionReferenceTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), + FirestoreOptions.newBuilder().setProjectId("test-project").build(), Mockito.mock(FirestoreRpc.class)); @Captor private ArgumentCaptor argCaptor; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/ConformanceTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/ConformanceTest.java index 8342b4b611f0..64e97ac86cbd 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/ConformanceTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/ConformanceTest.java @@ -133,11 +133,7 @@ public ConformanceTest() { firestoreMock = Mockito.spy( new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("projectID") - .setTimestampsInSnapshotsEnabled(true) - .build(), - firestoreRpc)); + FirestoreOptions.newBuilder().setProjectId("projectID").build(), firestoreRpc)); watchQuery = collection("projects/projectID/databases/(default)/documents/C").orderBy("a"); } diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/DocumentReferenceTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/DocumentReferenceTest.java index daa10e18ee37..eb4a165b1732 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/DocumentReferenceTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/DocumentReferenceTest.java @@ -94,10 +94,7 @@ public class DocumentReferenceTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), + FirestoreOptions.newBuilder().setProjectId("test-project").build(), Mockito.mock(FirestoreRpc.class)); @Captor private ArgumentCaptor commitCapture; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/FirestoreTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/FirestoreTest.java index 71557f9b84f4..2051b7b05939 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/FirestoreTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/FirestoreTest.java @@ -44,10 +44,7 @@ public class FirestoreTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), + FirestoreOptions.newBuilder().setProjectId("test-project").build(), Mockito.mock(FirestoreRpc.class)); @Captor private ArgumentCaptor getAllCapture; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java index 557ed6d00d10..564c1b335de3 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/QueryTest.java @@ -61,10 +61,7 @@ public class QueryTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), + FirestoreOptions.newBuilder().setProjectId("test-project").build(), Mockito.mock(FirestoreRpc.class)); @Captor private ArgumentCaptor runQuery; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java index c37631ee0688..528309195c9d 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TransactionTest.java @@ -77,11 +77,7 @@ public class TransactionTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), - firestoreRpc); + FirestoreOptions.newBuilder().setProjectId("test-project").build(), firestoreRpc); @Captor private ArgumentCaptor requestCapture; @Captor private ArgumentCaptor> streamObserverCapture; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WatchTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WatchTest.java index 43b713312643..7d450e397f7c 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WatchTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WatchTest.java @@ -97,11 +97,7 @@ public class WatchTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), - firestoreRpc); + FirestoreOptions.newBuilder().setProjectId("test-project").build(), firestoreRpc); @Captor private ArgumentCaptor> streamObserverCapture; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java index 299660fa4205..f29d87ca0948 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/WriteBatchTest.java @@ -52,10 +52,7 @@ public class WriteBatchTest { @Spy private FirestoreImpl firestoreMock = new FirestoreImpl( - FirestoreOptions.newBuilder() - .setProjectId("test-project") - .setTimestampsInSnapshotsEnabled(true) - .build(), + FirestoreOptions.newBuilder().setProjectId("test-project").build(), Mockito.mock(FirestoreRpc.class)); @Captor private ArgumentCaptor commitCapture; diff --git a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java index c935702f544b..c4940f6ff38b 100644 --- a/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java +++ b/google-cloud-clients/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITSystemTest.java @@ -86,8 +86,7 @@ public class ITSystemTest { @Before public void before() { - FirestoreOptions firestoreOptions = - FirestoreOptions.newBuilder().setTimestampsInSnapshotsEnabled(true).build(); + FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder().build(); firestore = firestoreOptions.getService(); randomColl = firestore.collection(