angulartypescriptfirebasegoogle-cloud-firestore

firebase.firestore.FieldValue.serverTimestamp() doesn't support Timestamp data type


 async createUser(uid: string, email: string) {
    await this.afs.doc<UserProfileModel>(FirestoreDbConstant.USER_PROFILES + `/${uid}`).set({
      email,
      createdDate: firebase.firestore.FieldValue.serverTimestamp(),
    });
  }

This model works

export interface UserProfileModel {
    email: string;
    createdDate?: firebase.firestore.FieldValue;
}

But Why I cannot use Timestamp here like so?

import { Timestamp } from '@firebase/firestore-types';

export interface UserProfileModel {
    email: string;
    createdDate?: Timestamp;
}

Then it gives this error:

(property) UserProfileModel.createdDate?: Timestamp Type 'FieldValue' is missing the following properties from type 'Timestamp': seconds, nanoseconds, toDate, toMillists(2739) user-profile.model.ts(11, 5): The expected type comes from property 'createdDate' which is declared here on type 'UserProfileModel'

The problem here is I need to use toDate() on the template. But it doesn't work with the createdDate?: firebase.firestore.FieldValue;

<p>{{invitedEvent.startDatetime.toDate() | amDateFormat: 'MMM DD'}}</p>

Solution

  • As you can see from the JavaScript API documentation for serverTimestamp():

    serverTimestamp(): FieldValue

    Returns a sentinel used with set() or update() to include a server-generated timestamp in the written data.

    Returns FieldValue

    It doesn't return a Timestamp type. It returns a FieldValue, whose value is actually just a placeholder for a special value that tell the server to generate the timestamp. The client doesn't generate this timestamp at all, since we can't trust the client device's clock.

    This means you can't really use the same model for reading and writing records that use server timestamps. On the way in, it will be a FieldValue. On the way out (when you query the document), it will be a Timestamp.