How to use FieldValue ServerTimestamp in TypeScript data model?

Viewed 789

I'm using TypeScript to define the data models for my documents in Firebase. When the document is being created the createdOn field will be the server timestamp sentinal, but otherwise it is a date. For example...

export interface Post<MODE extends 'create' | 'read'> {
  comment: string;
  createdOn: MODE extends 'create' ? FieldValue : Date;
}

I don't know how to properly define and assign to the createdOn property. First, I'm not really sure which firebase module to load the FieldValue type from. The best I could do was this and this seems a bit hokey...

import * as firebase from 'firebase';
type FieldValue = firebase.default.firestore.FieldValue;
export const SERVER_TIMESTAMP = firebase.default.firestore.FieldValue.serverTimestamp();

And then when I use it, this is what happens...

// Fails when used within cloud function
// Detected an object of type "FieldValue" that doesn't match the
// expected instance (found in field "createdOn"). Please ensure 
/// that the Firestore types you are using are from the same NPM package.

post.createdOn = SERVER_TIMESTAMP;

// But this works within cloud function

post.createdOn = admin.firestore.FieldValue.serverTimestamp();

Are the types of FieldValue different when called from within a cloud function and on the client? Can I simply import this type from some module that works from both cloud functions and client?

2 Answers

I think this is a known limitation confusing issue with the javascript SDKs.

https://github.com/firebase/firebase-js-sdk/issues/4246

If you are creating an item in Firestore from an admin app you need to use a different "serverTimestamp" object than when creating one from a client app.

Firebase has quite a few products in their lineup so it's not too intuitive and this can cause confusion. Here you can view all of the products and you can view how to properly implement each library.

In your case it seems you're missing firestore which you can import using:

import * as firebase from 'firebase/app';
import 'firebase/firestore';

Then you are able to use the Field value like so:

const timestamp = firebase.firestore.FieldValue.serverTimestamp();

Here is more information on Field values.

Related