4

When setting up firestore and angularfire2 in may 2018, you get this error message:

 @firebase/firestore: Firestore (4.10.1): 
The behavior for Date objects stored in Firestore is going to change
AND YOUR APP MAY BREAK.
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:

  const firestore = firebase.firestore();
  const settings = {/* your settings... */ timestampsInSnapshots: true};
  firestore.settings(settings);

With this change, timestamps stored in Cloud Firestore will be read back as
Firebase Timestamp objects instead of as system Date objects. So you will also
need to update code expecting a Date to instead expect a Timestamp. For example:

  // Old:
  const date = snapshot.get('created_at');
  // New:
  const timestamp = snapshot.get('created_at');
  const date = timestamp.toDate();

Please audit all existing usages of Date when you enable the new behavior. In a
future release, the behavior will change to the new behavior, so if you do not
follow these steps, YOUR APP MAY BREAK.

I am confused about what this will mean in practice in an Angular application, in the long term. Specifically:

  1. Will angularfire2 "wrap" around the firestore, and solve this issue by converting everything to JS-Date?
  2. Do we have to upgrade all queries against firestore be changed to use timestamp, and not JS date?
  3. Do we need to convert cast all timestamp values toDate(), like instructed in the snippet?

Thanks for your help.

update (more info) I found this info explaining why firestore moves from Date to Timestamp in @firebase/firestore-types:

A Timestamp represents a point in time independent of any time zone or calendar, represented as seconds and fractions of seconds at nanosecond resolution in UTC Epoch time. It is encoded using the Proleptic Gregorian Calendar which extends the Gregorian calendar backwards to year one. It is encoded assuming all minutes are 60 seconds long, i.e. leap seconds are "smeared" so that no leap second table is needed for interpretation. Range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.

This also mean that in typescript, you can get the type like this: import { Timestamp } from '@firebase/firestore-types'; Btw, if you go to @firebase/firestore-types/index.d.ts file, there is a link to github with more info.

DauleDK
  • 3,313
  • 11
  • 55
  • 98

1 Answers1

3

Question 1 "Will angularfire2 "wrap" around the firestore, and solve this issue by converting everything to JS-Date?"

No, that would not make sense since information could be lost (i.e. nano seconds).

Question 2 "Do we have to upgrade all queries against firestore be changed to use timestamp, and not JS date?"

I am not sure about this one, I will investigate. I suppose that you can use Date, but timestamp would be best.

Question 3 "Do we need to convert cast all timestamp values toDate(), like instructed in the snippet?"

That depends. If you wan't to use the timestamp in a datepicker for example, the datepicker probably does not support timestamp and thus must be converted. However some information can also be lost.

Timestamp vs Javascript Date (help wanted)

I created this small table to understand the choice of moving from Date to timestamp

+----------------+------------------------------+---------------------------------+-------------------------------------+
|                |        javascript Date       |      firestore "Timestamp"      |         comment/implication         |
+----------------+------------------------------+---------------------------------+-------------------------------------+
| precision      | milliseconds                 | nanosecond                      | better resolution. two objects      |
|                |                              |                                 | created right after each other can  |
|                |                              |                                 | have the same millisecond,          |
|                |                              |                                 | but not nanosecond.                 |
+----------------+------------------------------+---------------------------------+-------------------------------------+
| specific point | Can be both                  |      Yes - independent of       |           ? (help wanted)           |
| in time        |                              |  any time zone or calendar..."  |                                     |
+----------------+------------------------------+---------------------------------+-------------------------------------+
| range          |  8,640 * 10^12 milliseconds  |          Range is from:         |   This restriction on Timestamp,    |
|                | to either side of 01 January |      0001-01-01T00:00:00Z       |    makes it possible to convert     |
|                |          , 1970 UTC          |                to               |      to RFC 3339 date strings.      |
|                |                              | 9999-12-31T23:59:59.999999999Z. |                                     |
+----------------+------------------------------+---------------------------------+-------------------------------------+
| leap seconds   | ignored                      | leap seconds are "smeared"      | ? (help wanted)                     |
+----------------+------------------------------+---------------------------------+-------------------------------------+
| calendar       | Gregorian Calendar?          | Proleptic Gregorian Calendar    | The Gregorian Calendar              |
|                |                              |                                 | only goes back to 1582,             |
|                |                              |                                 | Proleptic goes back to 0001.        |
+----------------+------------------------------+---------------------------------+-------------------------------------+

Sources

I used the following sources of information:

  1. The error message you can see in the question
  2. The @firebase/firestore-types/index.d.ts file
  3. The link provided there to github
  4. The ECMAScript Language Specification
  5. This stackoverflow question.
DauleDK
  • 3,313
  • 11
  • 55
  • 98