skip to Main Content

I haven’t worked on my project in a while, so after updating firestore to the latest version I’m running into an issue with the server time stamps I had been using.

import { AngularFirestore } from '@angular/fire/compat/firestore';
import firebase from 'firebase/compat/app';
import 'firebase/firestore'

const timestamp = { timestamp: firebase.firestore.FieldValue.serverTimestamp() }

This has worked for a while, and would save a field in firestore as a timestamp type (see screenshot below)

When I try to run this after updating, I get the following console error:

ERROR TypeError: Cannot read properties of undefined (reading ‘FieldValue’)

I tried to update the imports to

import { serverTimestamp } from 'firebase/firestore';

and then use something like this to try setting the timestamp field

const timestampA = {timestamp: serverTimestamp()}

I’m getting errors trying to actually save it:

ERROR FirebaseError: Function addDoc() called with invalid data. Unsupported field value: a custom aj object (found in field timestamp in document Party-Management/8UcAzhIEPAwFqUTkwr71/Party-Inventory/uthoJHWfozdjZ5OyluBW)

Am I missing something here on how to get serverTimestamps to work in newer firebase versions?

Here is the the whole function that worked in prior versions:

  addInventory(inventoryAdd: any, pid: string, sid?: string, eid?: any) {
const inventoryCollectionRef = this.afs.collection(this.partyCollectionPath + pid + this.partyInventoryPath);
const timestamp = { timestamp: firebase.firestore.FieldValue.serverTimestamp() }
const sessionId = sid ? { sessionId: sid} : null;
const eventId = eid ? { eventId: eid } : null;
return inventoryCollectionRef.add({ ...inventoryAdd, ...timestamp, ...sessionId, ...eventId }).then(docRef => {
  return docRef.id
}).catch(error => console.error("Error adding document: ", error))

}

firestore

So, I’m getting a little bit more information on how this is behaving.

If I try to use this code to create my timestamp type object,
const timestamp = { timestamp: serverTimestamp() }
This code blows up:

inventoryCollectionRef.add({ ...inventoryAdd, ...timestamp, ...sessionId, ...eventId })

With this error message:

ERROR FirebaseError: Function addDoc() called with invalid data. Unsupported field value: a custom aj object (found in field timestamp in document Party-Management/8UcAzhIEPAwFqUTkwr71/Party-Inventory/NCi4Ad4a2jc8RjdKQdNm)

Which means that whatever is now in serverTimestamp() isn’t playing nicely with the ‘timestamp’ type i had used in the past.

If I change just the constant to this:

const timestamp = serverTimestamp()

The call actually goes through and saves a record to firestore, but when I actually look at the data in firestore it’s saving a string type with a field name of ‘_methodname’, and a value of ‘serverTimestamp’ which is obviously not what I want.

firestore types

I found some documentation on the Timestamp class in Firebase, so I’ll try looking at that too. (https://firebase.google.com/docs/reference/js/firestore_.timestamp)

In the end, I want to be able to specifically save the ‘timestamp’ type, and I’m sure there is a way to do it!

**Update: ** Ugh, I’m going to guess this has to do with my old implementation of angularFirestore and firebase, and probably some ‘hacky’ upgrades where I didn’t really understand what I was doing. I found current documentation that insinuates this is the correct way to do it still (https://firebase.google.com/docs/firestore/manage-data/add-data#server_timestamp), so I’m guessing I have some fun mismatches somewhere.

Unless someone has a ‘magic bullet’ fix, my next two steps are to try to figure out how to totally rip out the current version of angulare/firestore and firebase through ng and npm and try to install them fresh, potentially with some of the new implementations I’ve seen.

If that doesn’t work, I think it might be time for a full refactor and build up from scratch again.

2

Answers


  1. Chosen as BEST ANSWER

    Ok, so the issue was entirely on how I went about upgrading my angular fire and firebase through NG and NPM. Before upgrading, I was on v16 of angular and the following version of angular/fire and firebase:

    @angular/[email protected]
    [email protected]
    

    I started by using the ng update command to bring everything except for @angulare/fire to the latest version:

      @angular/cdk                       16.0.4 -> 17.1.1         ng update @angular/cdk
      @angular/cli                       16.0.5 -> 17.1.1         ng update @angular/cli
      @angular/core                      16.0.5 -> 17.1.1         ng update @angular/core
      @angular/fire                      7.6.1 -> 17.0.1          ng update @angular/fire
      @angular/material                  16.0.4 -> 17.1.1         ng update @angular/material
    

    If you try to go directly from 7x to the latest 17 on angulare/fire, NPM doesn't like the huge version jump and will give you an error message. So to get angulare/fire upgraded, I went into the package.json and directly edited the version number from '7.6.1' to '17.0.1'. I then ran 'npm install', which picked up the changed version number in package.json and installed the current @angular/fire version as expected.

    Just doing that ended up giving me the exact same FieldValue error as before, so I ALSO had to use the package.json trick to upgrade firebase from 9.22.2 to the latest 10.7.2. Once firebase was also updated, all of my previous functions were working as expected.

    Hopefully if someone else runs into a similar issue, they'll find this helpful. Thanks for everyone who helped me narrow down the issue!


  2. If I was you for this I would use the native firebase library – you don’t need to import

    remove

    import { AngularFirestore } from '@angular/fire/compat/firestore';
    

    you’ve already imported the library and this would create conflicts.
    then you need to import them.

    { serverTimestamp,} from @firebase/firestore**
    

    second there is no reason to wrap an object around the field, that would create issues.
    you should only use serverTimestamp() now.

    "Returns a sentinel used with @firebase/firestore/lite#(setDoc:1) or @firebase/firestore/lite#(updateDoc:1) to include a server-generated timestamp in the written data."

    this doesn’t like the way the data is presented to it. For what it’s worth I generally just use DayJS to deal with time and date issues.
    that said try this. it’s expecting a JSON representation of the time and date and you are not presenting what it expects.

    const timestamp = JSON.stringify(serverTimestamp())
    

    If you have LinkedIn I wrote a blog about how to properly setup Firebase

    [How To Setup Firebase][1]

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search