Skip to content

Commit 72cb763

Browse files
author
Brian Chen
authored
Merge a8cfd15 into 795f31a
2 parents 795f31a + a8cfd15 commit 72cb763

File tree

10 files changed

+15
-163
lines changed

10 files changed

+15
-163
lines changed

.changeset/strange-rabbits-wait.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'firebase': major
3+
'@firebase/firestore': major
4+
'@firebase/firestore-types': major
5+
---
6+
7+
Removed the `timestampsInSnapshots` option from `FirestoreSettings`. Now, Firestore always returns `Timestamp` values for all timestamp values.

packages/firebase/index.d.ts

-34
Original file line numberDiff line numberDiff line change
@@ -7825,40 +7825,6 @@ declare namespace firebase.firestore {
78257825
/** Whether to use SSL when connecting. */
78267826
ssl?: boolean;
78277827

7828-
/**
7829-
* Specifies whether to use `Timestamp` objects for timestamp fields in
7830-
* `DocumentSnapshot`s. This is enabled by default and should not be
7831-
* disabled.
7832-
*
7833-
* Previously, Firestore returned timestamp fields as `Date` but `Date`
7834-
* only supports millisecond precision, which leads to truncation and
7835-
* causes unexpected behavior when using a timestamp from a snapshot as a
7836-
* part of a subsequent query.
7837-
*
7838-
* Now, Firestore returns `Timestamp` values for all timestamp values stored
7839-
* in Cloud Firestore instead of system `Date` objects, avoiding this kind
7840-
* of problem. Consequently, you must update your code to handle `Timestamp`
7841-
* objects instead of `Date` objects.
7842-
*
7843-
* If you want to **temporarily** opt into the old behavior of returning
7844-
* `Date` objects, you may **temporarily** set `timestampsInSnapshots` to
7845-
* false. Opting into this behavior will no longer be possible in the next
7846-
* major release of Firestore, after which code that expects Date objects
7847-
* **will break**.
7848-
*
7849-
* @example **Using Date objects in Firestore.**
7850-
* // With deprecated setting `timestampsInSnapshot: true`:
7851-
* const date : Date = snapshot.get('created_at');
7852-
* // With new default behavior:
7853-
* const timestamp : Timestamp = snapshot.get('created_at');
7854-
* const date : Date = timestamp.toDate();
7855-
*
7856-
* @deprecated This setting will be removed in a future release. You should
7857-
* update your code to expect `Timestamp` objects and stop using the
7858-
* `timestampsInSnapshots` setting.
7859-
*/
7860-
timestampsInSnapshots?: boolean;
7861-
78627828
/**
78637829
* An approximate cache size threshold for the on-disk data. If the cache grows beyond this
78647830
* size, Firestore will start removing data that hasn't been recently used. The size is not a

packages/firestore-types/index.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export const CACHE_SIZE_UNLIMITED: number;
2626
export interface Settings {
2727
host?: string;
2828
ssl?: boolean;
29-
timestampsInSnapshots?: boolean;
3029
cacheSizeBytes?: number;
3130
experimentalForceLongPolling?: boolean;
3231
ignoreUndefinedProperties?: boolean;

packages/firestore/exp/src/api/snapshot.ts

-2
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ export class DocumentSnapshot<T = DocumentData> extends LiteDocumentSnapshot<
236236
} else {
237237
const userDataWriter = new UserDataWriter(
238238
this._firestoreImpl._databaseId,
239-
/* timestampsInSnapshots= */ true,
240239
options?.serverTimestamps || DEFAULT_SERVER_TIMESTAMP_BEHAVIOR,
241240
key =>
242241
new DocumentReference(
@@ -276,7 +275,6 @@ export class DocumentSnapshot<T = DocumentData> extends LiteDocumentSnapshot<
276275
if (value !== null) {
277276
const userDataWriter = new UserDataWriter(
278277
this._firestoreImpl._databaseId,
279-
/* timestampsInSnapshots= */ true,
280278
options.serverTimestamps || DEFAULT_SERVER_TIMESTAMP_BEHAVIOR,
281279
key =>
282280
new DocumentReference(this._firestore, this._converter, key.path),

packages/firestore/lite/src/api/snapshot.ts

-2
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ export class DocumentSnapshot<T = DocumentData> {
171171
} else {
172172
const userDataWriter = new UserDataWriter(
173173
this._firestore._databaseId,
174-
/* timestampsInSnapshots= */ true,
175174
/* serverTimestampBehavior=*/ 'none',
176175
key =>
177176
new DocumentReference(
@@ -204,7 +203,6 @@ export class DocumentSnapshot<T = DocumentData> {
204203
if (value !== null) {
205204
const userDataWriter = new UserDataWriter(
206205
this._firestore._databaseId,
207-
/* timestampsInSnapshots= */ true,
208206
/* serverTimestampBehavior=*/ 'none',
209207
key =>
210208
new DocumentReference(this._firestore, this._converter, key.path),

packages/firestore/src/api/database.ts

-35
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ import { Provider } from '@firebase/component';
144144
// settings() defaults:
145145
const DEFAULT_HOST = 'firestore.googleapis.com';
146146
const DEFAULT_SSL = true;
147-
const DEFAULT_TIMESTAMPS_IN_SNAPSHOTS = true;
148147
const DEFAULT_FORCE_LONG_POLLING = false;
149148
const DEFAULT_IGNORE_UNDEFINED_PROPERTIES = false;
150149

@@ -185,8 +184,6 @@ class FirestoreSettings {
185184
/** Whether to use SSL when connecting. */
186185
readonly ssl: boolean;
187186

188-
readonly timestampsInSnapshots: boolean;
189-
190187
readonly cacheSizeBytes: number;
191188

192189
readonly experimentalForceLongPolling: boolean;
@@ -218,7 +215,6 @@ class FirestoreSettings {
218215
'host',
219216
'ssl',
220217
'credentials',
221-
'timestampsInSnapshots',
222218
'cacheSizeBytes',
223219
'experimentalForceLongPolling',
224220
'ignoreUndefinedProperties'
@@ -232,35 +228,13 @@ class FirestoreSettings {
232228
);
233229
this.credentials = settings.credentials;
234230

235-
validateNamedOptionalType(
236-
'settings',
237-
'boolean',
238-
'timestampsInSnapshots',
239-
settings.timestampsInSnapshots
240-
);
241-
242231
validateNamedOptionalType(
243232
'settings',
244233
'boolean',
245234
'ignoreUndefinedProperties',
246235
settings.ignoreUndefinedProperties
247236
);
248237

249-
// Nobody should set timestampsInSnapshots anymore, but the error depends on
250-
// whether they set it to true or false...
251-
if (settings.timestampsInSnapshots === true) {
252-
logError(
253-
"The setting 'timestampsInSnapshots: true' is no longer required " +
254-
'and should be removed.'
255-
);
256-
} else if (settings.timestampsInSnapshots === false) {
257-
logError(
258-
"Support for 'timestampsInSnapshots: false' will be removed soon. " +
259-
'You must update your code to handle Timestamp objects.'
260-
);
261-
}
262-
this.timestampsInSnapshots =
263-
settings.timestampsInSnapshots ?? DEFAULT_TIMESTAMPS_IN_SNAPSHOTS;
264238
this.ignoreUndefinedProperties =
265239
settings.ignoreUndefinedProperties ?? DEFAULT_IGNORE_UNDEFINED_PROPERTIES;
266240

@@ -300,7 +274,6 @@ class FirestoreSettings {
300274
return (
301275
this.host === other.host &&
302276
this.ssl === other.ssl &&
303-
this.timestampsInSnapshots === other.timestampsInSnapshots &&
304277
this.credentials === other.credentials &&
305278
this.cacheSizeBytes === other.cacheSizeBytes &&
306279
this.experimentalForceLongPolling ===
@@ -712,12 +685,6 @@ export class Firestore implements PublicFirestore, FirebaseService {
712685
setLogLevel(level);
713686
}
714687

715-
// Note: this is not a property because the minifier can't work correctly with
716-
// the way TypeScript compiler outputs properties.
717-
_areTimestampsInSnapshotsEnabled(): boolean {
718-
return this._settings.timestampsInSnapshots;
719-
}
720-
721688
// Visible for testing.
722689
_getSettings(): PublicSettings {
723690
return this._settings;
@@ -1400,7 +1367,6 @@ export class DocumentSnapshot<T = DocumentData>
14001367
} else {
14011368
const userDataWriter = new UserDataWriter(
14021369
this._firestore._databaseId,
1403-
this._firestore._areTimestampsInSnapshotsEnabled(),
14041370
options.serverTimestamps || 'none',
14051371
key =>
14061372
new DocumentReference(key, this._firestore, /* converter= */ null),
@@ -1426,7 +1392,6 @@ export class DocumentSnapshot<T = DocumentData>
14261392
if (value !== null) {
14271393
const userDataWriter = new UserDataWriter(
14281394
this._firestore._databaseId,
1429-
this._firestore._areTimestampsInSnapshotsEnabled(),
14301395
options.serverTimestamps || 'none',
14311396
key => new DocumentReference(key, this._firestore, this._converter),
14321397
bytes => new Blob(bytes)

packages/firestore/src/api/user_data_writer.ts

+2-11
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ export type ServerTimestampBehavior = 'estimate' | 'previous' | 'none';
5757
export class UserDataWriter {
5858
constructor(
5959
private readonly databaseId: DatabaseId,
60-
private readonly timestampsInSnapshots: boolean,
6160
private readonly serverTimestampBehavior: ServerTimestampBehavior,
6261
private readonly referenceFactory: (
6362
key: DocumentKey
@@ -128,17 +127,9 @@ export class UserDataWriter {
128127
}
129128
}
130129

131-
private convertTimestamp(value: ProtoTimestamp): Timestamp | Date {
130+
private convertTimestamp(value: ProtoTimestamp): Timestamp {
132131
const normalizedValue = normalizeTimestamp(value);
133-
const timestamp = new Timestamp(
134-
normalizedValue.seconds,
135-
normalizedValue.nanos
136-
);
137-
if (this.timestampsInSnapshots) {
138-
return timestamp;
139-
} else {
140-
return timestamp.toDate();
141-
}
132+
return new Timestamp(normalizedValue.seconds, normalizedValue.nanos);
142133
}
143134

144135
private convertReference(name: string): _DocumentKeyReference<DocumentData> {

packages/firestore/test/integration/api/fields.test.ts

-71
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ import {
2828
import { DEFAULT_SETTINGS } from '../util/settings';
2929

3030
const FieldPath = firebaseExport.FieldPath;
31-
const FieldValue = firebaseExport.FieldValue;
3231
const Timestamp = firebaseExport.Timestamp;
33-
const usesFunctionalApi = firebaseExport.usesFunctionalApi;
3432

3533
// Allow custom types for testing.
3634
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -354,44 +352,6 @@ apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => {
354352
return { timestamp: ts, nested: { timestamp2: ts } };
355353
};
356354

357-
// timestampInSnapshots is not support in the modular API.
358-
// eslint-disable-next-line no-restricted-properties
359-
(usesFunctionalApi() ? it.skip : it)(
360-
'are returned as native dates if timestampsInSnapshots set to false',
361-
() => {
362-
const settings = { ...DEFAULT_SETTINGS };
363-
settings['timestampsInSnapshots'] = false;
364-
365-
const timestamp = new Timestamp(100, 123456789);
366-
const testDocs = { a: testDataWithTimestamps(timestamp) };
367-
return withTestCollectionSettings(
368-
persistence,
369-
settings,
370-
testDocs,
371-
coll => {
372-
return coll
373-
.doc('a')
374-
.get()
375-
.then(docSnap => {
376-
expect(docSnap.get('timestamp'))
377-
.to.be.a('date')
378-
.that.deep.equals(timestamp.toDate());
379-
expect(docSnap.data()!['timestamp'])
380-
.to.be.a('date')
381-
.that.deep.equals(timestamp.toDate());
382-
383-
expect(docSnap.get('nested.timestamp2'))
384-
.to.be.a('date')
385-
.that.deep.equals(timestamp.toDate());
386-
expect(docSnap.data()!['nested']['timestamp2'])
387-
.to.be.a('date')
388-
.that.deep.equals(timestamp.toDate());
389-
});
390-
}
391-
);
392-
}
393-
);
394-
395355
it('are returned as Timestamps', () => {
396356
const timestamp = new Timestamp(100, 123456000);
397357
// Timestamps are currently truncated to microseconds after being written to
@@ -423,37 +383,6 @@ apiDescribe('Timestamp Fields in snapshots', (persistence: boolean) => {
423383
});
424384
});
425385
});
426-
427-
// timestampInSnapshots is not support in the modular API.
428-
// eslint-disable-next-line no-restricted-properties
429-
(usesFunctionalApi() ? it.skip : it)(
430-
'timestampsInSnapshots affects server timestamps',
431-
() => {
432-
const settings = { ...DEFAULT_SETTINGS };
433-
settings['timestampsInSnapshots'] = false;
434-
const testDocs = {
435-
a: { timestamp: FieldValue.serverTimestamp() }
436-
};
437-
438-
return withTestCollectionSettings(
439-
persistence,
440-
settings,
441-
testDocs,
442-
coll => {
443-
return coll
444-
.doc('a')
445-
.get()
446-
.then(docSnap => {
447-
expect(
448-
docSnap.get('timestamp', {
449-
serverTimestamps: 'estimate'
450-
})
451-
).to.be.an.instanceof(Date);
452-
});
453-
}
454-
);
455-
}
456-
);
457386
});
458387

459388
apiDescribe('`undefined` properties', (persistence: boolean) => {

packages/firestore/test/unit/remote/serializer.helper.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ export function serializerTest(
310310

311311
it('converts TimestampValue from proto', () => {
312312
const examples = [
313-
new Date(Date.UTC(2016, 0, 2, 10, 20, 50, 850)),
314-
new Date(Date.UTC(2016, 5, 17, 10, 50, 15, 0))
313+
new Timestamp(1451730050, 850000000),
314+
new Timestamp(1466160615, 0)
315315
];
316316

317317
const expectedJson = [
@@ -339,25 +339,25 @@ export function serializerTest(
339339
userDataWriter.convertValue({
340340
timestampValue: '2017-03-07T07:42:58.916123456Z'
341341
})
342-
).to.deep.equal(new Timestamp(1488872578, 916123456).toDate());
342+
).to.deep.equal(new Timestamp(1488872578, 916123456));
343343

344344
expect(
345345
userDataWriter.convertValue({
346346
timestampValue: '2017-03-07T07:42:58.916123Z'
347347
})
348-
).to.deep.equal(new Timestamp(1488872578, 916123000).toDate());
348+
).to.deep.equal(new Timestamp(1488872578, 916123000));
349349

350350
expect(
351351
userDataWriter.convertValue({
352352
timestampValue: '2017-03-07T07:42:58.916Z'
353353
})
354-
).to.deep.equal(new Timestamp(1488872578, 916000000).toDate());
354+
).to.deep.equal(new Timestamp(1488872578, 916000000));
355355

356356
expect(
357357
userDataWriter.convertValue({
358358
timestampValue: '2017-03-07T07:42:58Z'
359359
})
360-
).to.deep.equal(new Timestamp(1488872578, 0).toDate());
360+
).to.deep.equal(new Timestamp(1488872578, 0));
361361
});
362362

363363
it('converts TimestampValue to string (useProto3Json=true)', () => {

packages/firestore/test/util/helpers.ts

-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ export type TestSnapshotVersion = number;
111111
export function testUserDataWriter(): UserDataWriter {
112112
return new UserDataWriter(
113113
TEST_DATABASE_ID,
114-
/* timestampsInSnapshots= */ false,
115114
'none',
116115
key => new DocumentReference(key, FIRESTORE, /* converter= */ null),
117116
bytes => new Blob(bytes)

0 commit comments

Comments
 (0)