wovalle / fireorm

ORM for firestore 🔥
https://fireorm.js.org
MIT License
559 stars 75 forks source link

firebase-admin SDK Timestamps no longer compatible with fireorm collection-update method #328

Open iKK001 opened 9 months ago

iKK001 commented 9 months ago

The update method of BaseFirestoreRepository of fireorm cannot deal with a date that is created with neest 'firebase-admin' SDK v11.11.1 anymore. (i.e. update(item: T): Promise<T>;)

import { Timestamp } from 'firebase-admin';    // DOES NOT WORK !!!!!!
import { Timestamp } from '@google-cloud/firestore';   // WORKS !!!!!!!

async updateApi(
  trucId: String,
): Promise<Truc | undefined> {
  const truc: Truc = await this.findTruc(trucID);

  let updateTruc = truc;

  updateTruc.changedAt = Timestamp.fromDate(new Date());

  // filter out fields with undefined values from the updateTruc
  for (const key in updateTruc) {
    if (updateTruc[key] === undefined) {
      delete updateTruc[key];
    }
  }

  // Update the Firestore document with the updateTruc fields
  await this.update({ ...truc, ...updateTruc });

  return updateTruc;
}

Before, with firebase-admin SDK version 11.9.0, everything worked:

"dependencies": {
    "firebase-admin": "^11.9.0"
},

This works with v11.9.0:

import { firestore } from 'firebase-admin';

updateTruc.changedAt  = firestore.Timestamp.fromDate(new Date());

But now, with firebase-admin SDK version 11.11.1, the collection-udpate crashes:

"dependencies": {
    "firebase-admin": "^11.11.1"
  },
import { Timestamp } from 'firebase-admin';

updateTruc.changedAt  = Timestamp.fromDate(new Date());

The error message is:

Update() requires either a single JavaScript object or an alternating list of field/value pairs that can be followed by an optional precondition. Value for argument "dataOrField" is not a valid Firestore document. Detected an object of type "Timestamp" that doesn't match the expected instance.

After some more investigation:

The way it still works is as follows !!!!!!

"dependencies": {
    "@google-cloud/firestore": "^7.1.0",
},
import { Timestamp } from '@google-cloud/firestore';

updateTruc.changedAt  = Timestamp.fromDate(new Date());

Summary:

@google-cloud/firestore 7.1.0 WORKS (calling updateTruc.changedAt = Timestamp.fromDate(new Date());)

firebase-admin 11.9.0 WORKS (calling updateTruc.changedAt = firestore.Timestamp.fromDate(new Date());)

firebase-admin 11.11.1 DOES NOT WORK !!!!!! (calling updateTruc.changedAt = Timestamp.fromDate(new Date());)

It seems that fireorm can only handle Timestamps from @google-cloud/firestore - but no longer with newest version of firebase-admin v11.11.1. (It was able to do it with firebase-admin v10.9.0 - but no longer with v11.11.1 anymore).

So clearly, the firebase-admin SDK added an incompatibility for dates with respect to fireorm updates.

Can fireorm please be fully compatible again to newest fierebase-admin SDK ??

Or what 's the problem suddenly with firebase-admin v11.11.1 ??

RomainFayolle commented 5 months ago

Hi ! I have a similar issue: On project 1 (WORKS):

import * as admin from 'firebase-admin';
item.date = new admin.firestore.Timestamp(timestampData);
await admin.firestore().collection('test').doc(test.id).update({ item: item });

"firebase-admin": "^9.8.0"

On project 2 (DOESN'T WORK):

import * as admin from 'firebase-admin';
const { Timestamp } = require('@google-cloud/firestore'); // Had to change here because previous one was making error
item.date = new Timestamp(timestampData);
await admin.firestore().collection('test').doc(test.id).update({ item: item });
Error: Update() requires either a single JavaScript object or an alternating list of field/value pairs that can be followed by an optional precondition. Value for argument "dataOrField" is not a valid Firestore document. Detected an object of type "Timestamp" that doesn't match the expected instance (found in field "item.date"). Please ensure that the Firestore types you are using are from the same NPM package.)

"firebase-admin": "^11.5.0"

In the end I followed this guy solution: https://stackoverflow.com/questions/68384853/firebase-firestore-timestamp-fromdate-is-undefined and save the date as a JS date item.date = new Date(timestampData._seconds * 1000);