0
votes

I get the exception when I try to access a firebase.firestore.Timestamp (trialEnds) on a document using:

   <ng-container *ngIf="account$ | async as account;">
   // Listing out other account info works fine here...
   // Then an exception on trialEnds access
   <span *ngIf="account.trialEnds != null">
      {{account.trialEnds.toDate() |  date: 'M/d/yyyy'}})
   </span>

The exception I get is like this:

core.js:3828 ERROR TypeError: account_r9062.trialEnds.toDate is not a function at HeaderComponent_ng_container_14_ng_container_1_span_5_Template (header.component.html:38) at executeTemplate (core.js:7485) at refreshView (core.js:7362) at refreshDynamicEmbeddedViews (core.js:8428) at refreshView (core.js:7382) at refreshDynamicEmbeddedViews (core.js:8428) at refreshView (core.js:7382) at refreshDynamicEmbeddedViews (core.js:8428) at refreshView (core.js:7382) at refreshComponent (core.js:8492)

Here is how I set up the data in my component:

   var trialDays = 14
   var trialEndDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + trialDays)
   var trialEnds = firebase.firestore.Timestamp.fromDate(trialEndDate)
   var account: Account = {
   ...
      trialEnds: trialEnds
   }

The data shows up fine in the Firestore console, but the bizarre part is that if I update it in the console WITHOUT changing the data at all, I can read it just fine. There is literally no difference between the programatically set value and the manually updated value on the document:

enter image description here

It also throws an exception on other calls like toMillis as well. What is going on?

2
try to move account.trialEnds.toDate() to js, store in a variable and use that in dom string interpolation - Praveen Soni
In presented code you are not getting data from database, but you are just using package code to create new timestamp. While in explanation you are saying that " I update it in the console WITHOUT changing the data at all, I can read it just fine". Than you are adding screenshot from database... Presented code is not matching presented issue description. Can you pass the code in which you are getting data from firestore? - vitooh
Sorry if that was unclear. The template is getting the account observable (account$) from Firestore. That does work correctly. If I set the trialEnds as indicated using a timestamp, it "looks" like it is entered fine when I view it in the Firestore console. But when I try to read it in and call either toMillis or toDate on the timestamp I get the exception. And as indicated, trialEnds does exist, it is just somehow wrong... - Love to Code

2 Answers

0
votes

In your type file for account, is trialEnds definded as type of Timestamp

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

export interface Account {
  trialEnds: Timestamp;
}
0
votes

I found a workaround. Instead of calling toDate on the timestamp, I create my own variable tied to the observable as:

   ngOnInit() {
      try {
         this.account$.subscribe(account => {
            this.trialExpiration = account === null || account.trialEnds === null ?
               null : new Date(account.trialEnds.seconds * 1000);
         })
      } catch (error) {
         console.log(error)
      }
   }

Then in the template, use:

   <span *ngIf="trialExpiration != null">
      Trial Expires on {{trialExpiration |  date: 'M/d/yyyy'}}
   </span>

It works, but can anyone explain why calling seconds on the timestamp but toMillis or toDate throws?