Reputation: 65860
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>
Upvotes: 6
Views: 3748
Reputation: 51
Another option for this is to define your own interface that partially extends both Timestamp and FieldValue
export interface MyTimestamp extends Partial<FieldValue>, Partial<Timestamp>
{
isEqual: (other: any) => boolean;
valueOf: () => any;
}
Then you can set your timestamp props to:
export interface UserProfileModel {
email: string;
createdDate?: MyTimestamp;
}
You'll then get proper types for both writing and reading to firestore
The one caveat is that all props and functions are now optional so if you want to call toDate()
on Timestamp for example you'll need to use ?
user.createdDate?.toDate?.()
Writing:
user.createdDate = FieldValue.serverTimestamp();
Reading:
user.createdDate?.toDate?.();
Upvotes: 0
Reputation: 106
This might be better than 'any' or duplicating models :
lastModified: Timestamp | FieldValue;
Upvotes: 5
Reputation: 317322
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.
Upvotes: 7