Skip to content

[Firestore] admin.firestore.Timestamp.now() fails with firebase-admin 11, works in 10.3 (emulator) #1827

Closed

Description

@tofsjonas

[REQUIRED] Step 2: Describe your environment

  • Operating System version: macOS Monterey 12.4
  • Firebase SDK version: 11.3.0
  • Firebase Product: Firestore
  • Node.js version: v16.14.2
  • NPM version: 8.15.0

tsconfig.json

{
  "compilerOptions": {
    "lib": ["ES2020"],
    "module": "commonjs",
    "target": "ES2020",
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "outDir": "dist",
    "sourceMap": true,
    "strict": true,
    "allowSyntheticDefaultImports": true
  },
  "compileOnSave": true,
  "include": ["src"],
  "exclude": ["node_modules", "**/node_modules/*"]
}

package.json

{
  "name": "functions",
  "scripts": {
    "build": "rm -rf dist && tsc",
    "watch": "rm -rf dist && npx tsc -w --skipLibCheck --noEmitOnError",
    "serve": "firebase emulators:start --import=./.cache --export-on-exit",
    "deploy": "firebase deploy --only hosting",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "16"
  },
  "main": "dist/index.js",
  "dependencies": {
    "@firebase/app-compat": "^0.1.29",
    "axios": "^0.27.2",
    "cors": "^2.8.5",
    "firebase-admin": "^11.0.0",
    "firebase-functions": "^3.22.0",
    "stripe": "^9.14.0"
  },
  "devDependencies": {
    "@firebase/app-types": "^0.7.0",
    "@types/cors": "^2.8.12",
    "@types/stripe-v3": "^3.1.27",
    "firebase-functions-test": "^2.2.0",
    "jest": "^28.1.3",
    "typescript": "^4.7.4"
  },
  "private": true
}

[REQUIRED] Step 3: Describe the problem

admin.firestore.Timestamp.now() throws TypeError: Cannot read properties of undefined (reading 'now') (~same with admin.firestore.increment(1)).

In emulator, I haven't dared try it "live".

Steps to reproduce / Relevant Code:

test.ts

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
export const test = functions.region('europe-west1').https.onRequest(async (request, response) => {
  const res = await admin.firestore().collection('mytable').add({
    createdAt: admin.firestore.Timestamp.now(),
  })
  response.json({
    id: res.id,
  })
})

Result:

TypeError: Cannot read properties of undefined (reading 'now')

Activity

  1. google-oss-bot commented on Jul 21, 2022

    @google-oss-bot

    I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

  2. Joebayld commented on Jul 23, 2022

    @Joebayld

    It appears I'm having the same issue with the delete FieldValue. I get this error TypeError: Cannot read properties of undefined (reading 'delete').

    This looks to be yet another bug that has happened with firebase code releases. It seems like something always breaks on major releases these days.

  3. AkshayChhajed1998 commented on Aug 1, 2022

    @AkshayChhajed1998

    I am having same issues on emulator with new admin.firestore.Timestamp(s,ns) says Timestamp() is not the constructor , but works good live

  4. milo- commented on Aug 2, 2022

    @milo-

    Also experiencing the same issue, and firestore.v1.FirestoreAdminClient is also undefined

  5. magician11 commented on Aug 2, 2022

    @magician11

    I rolled back to v10.3.0 and admin.firestore.Timestamp.now() works again.

  6. lahirumaramba commented on Aug 2, 2022

    @lahirumaramba
    Member

    Thank you for reporting this issue. This might have been caused by the Firestore version bump in Admin SDK v11.
    In the meantime could try adding import { Timestamp } from 'firebase-admin/firestore' as a workaround? It seemed to have worked in #1793

  7. self-assigned this
    on Aug 2, 2022
  8. tofsjonas commented on Aug 3, 2022

    @tofsjonas
    Author

    When I do import { Timestamp } from 'firebase-admin/firestore' I get this:

    Unable to resolve path to module 'firebase-admin/firestore'.eslint import/no-unresolved

    😢

    This seems to work: import type { DocumentReference, DocumentData, Timestamp } from 'firebase-admin/firestore' 🤔🤯

  9. Joebayld commented on Aug 4, 2022

    @Joebayld

    Thank you for reporting this issue. This might have been caused by the Firestore version bump in Admin SDK v11.
    In the meantime could try adding import { Timestamp } from 'firebase-admin/firestore' as a workaround? It seemed to have worked in #1793

    What about for the delete field value?

    Any idea when this can be patched?

  10. lahirumaramba commented on Aug 8, 2022

    @lahirumaramba
    Member

    It seems like as we move on to the modular SDK we should import the types as needed.
    The following seems to work for me:

    Node.js

    const { initializeApp } = require('firebase-admin/app');
    const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');
    
    initializeApp();
    
    const f = getFirestore();
    const t = Timestamp.now();
    const fv = FieldValue.delete();
    

    TypeScript

    import { getFirestore, Timestamp, FieldValue, Firestore } from 'firebase-admin/firestore';
    import { initializeApp } from 'firebase-admin/app';
    
    initializeApp()
    
    const f: Firestore = getFirestore();
    const t: Timestamp = Timestamp.now();
    const fv: FieldValue = FieldValue.delete();
    

    TypeScript

    import * as admin from 'firebase-admin';
    
    admin.initializeApp();
    
    const f = admin.firestore();
    const t = admin.firestore.Timestamp.now();
    const fv = admin.firestore.FieldValue.delete();
    

    tsconfig.json

    {
      "compilerOptions": {
        "module": "commonjs",
        "esModuleInterop": true,
        "target": "es6",
        "moduleResolution": "node",
        "sourceMap": true,
        "outDir": "dist"
      },
      "lib": ["es2015"]
    }
    

    package.json

    {
      "name": "repro",
      "version": "1.0.0",
      "main": "dist/test.js",
      "scripts": {
        "start": "tsc && node dist/test.js"
      },
      "engines": {
        "node": "16"
      },
      "devDependencies": {
        "typescript": "^4.7.4"
      },
      "dependencies": {
        "firebase-admin": "^11.0.1"
      }
    }
    
    ├─┬ firebase-admin@11.0.1
    │ ├── @fastify/busboy@1.1.0
    │ ├── @firebase/database-compat@0.2.4
    │ ├── @firebase/database-types@0.9.12
    │ ├── @google-cloud/firestore@5.0.2
    │ ├── @google-cloud/storage@6.3.0
    │ ├── @types/node@18.6.5
    │ ├── jsonwebtoken@8.5.1
    │ ├── jwks-rsa@2.1.4
    │ ├── node-forge@1.3.1
    │ └── uuid@8.3.2
    └── typescript@4.7.4
    
  11. tofsjonas commented on Aug 9, 2022

    @tofsjonas
    Author

    Ah.

    The problem was (is) eslint-plugin-import 😢

    This will throw lint errors:

    import { getFirestore, Timestamp, FieldValue, Firestore } from 'firebase-admin/firestore';
    import { initializeApp } from 'firebase-admin/app';

    Unable to resolve path to module 'firebase-admin/app'. eslint import/no-unresolved

    whereas this will not (which I only tried because I copy/pasted your code):

    const { initializeApp } = require('firebase-admin/app');
    const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');

    The "solution" is to not use the plugin anymore. But I would like to..

    Do you have any idea what that's about?

    Failing eslintrc.js:

      extends: [
        'eslint:recommended',
        'plugin:import/recommended',
        'plugin:import/typescript',

    Passing eslintrc.js:

      extends: [
        'eslint:recommended',
        // 'plugin:import/recommended',
        // 'plugin:import/typescript',
  12. Joebayld commented on Aug 11, 2022

    @Joebayld

    It seems like as we move on to the modular SDK we should import the types as needed. The following seems to work for me:

    So is this the way of using the new version of the library with typescript? I can update my code accordingly, just want to make sure this is the correct solution or just a temporary fix.

    Also, can the library be fixed so the old way isn't an option in typescript anymore? Right now the error is thrown only at runtime but the types think it's okay as is (which it obviously isn't).

  13. lahirumaramba commented on Aug 11, 2022

    @lahirumaramba
    Member

    @Joebayld yes, if you are using the modular SDK then this is the correct way to import the types. For the issue you are facing with the previous syntax, could you provide us with a minimal repro by any chance? Thank you!

  14. Joebayld commented on Aug 11, 2022

    @Joebayld

    @Joebayld yes, if you are using the modular SDK then this is the correct way to import the types. For the issue you are facing with the previous syntax, could you provide us with a minimal repro by any chance? Thank you!

    I think I see the issue then. I was using the older style imports (which worked in v10 and v11, but had the runtime issue).

    import * as admin from "firebase-admin";
    
    admin.firestore.FieldValue.delete()

    With the above code on the latest version, this appears to be fine in typescript but doesn't work. I switched everything to the new modular imports and it seems to be okay.

  15. JFGHT commented on Aug 24, 2022

    @JFGHT

    With the non-modular approach, we are having the same problem.

  16. ansells commented on Aug 24, 2022

    @ansells

    Ah.

    The problem was (is) eslint-plugin-import 😢

    This will throw lint errors:

    import { getFirestore, Timestamp, FieldValue, Firestore } from 'firebase-admin/firestore';
    import { initializeApp } from 'firebase-admin/app';

    Unable to resolve path to module 'firebase-admin/app'. eslint import/no-unresolved

    I'm having this same issue and had to explicitly ignore the rule for this import:

    // eslint-disable-next-line import/no-unresolved 
    import {Timestamp} from "firebase-admin/firestore";
  17. pascalbe-dev commented on Aug 26, 2022

    @pascalbe-dev

    I also stumbled across that issue. Using the modular imports fixed the issue. Thanks for the hint :)

    I think - since this is a breaking change in usage with the emulator - this should be noted in the release notes.

  18. pascalbe-dev commented on Aug 26, 2022

    @pascalbe-dev

    Running my jest tests for code, which imports getFirestore the modular way now fails.
    It is unhappy with the following statement in the /node_modules/firebase-admin/lib/esm/firestore/index.js file.

    import mod from "../../firestore/index.js";

    It says: SyntaxError: Cannot use import statement outside a module

    Has anyone experienced this issue as well or knows how to fix it?

  19. mariamghalleb commented on Oct 25, 2022

    @mariamghalleb

    Also experiencing the same issue, and firestore.v1.FirestoreAdminClient is also undefined

    import * as firestore from 'firebase-admin/firestore'
    fixed it for me

  20. abMarlim commented on Oct 27, 2022

    @abMarlim

    @ lahirumaramba you are a lifesave, thanks <3

  21. lahirumaramba commented on Oct 27, 2022

    @lahirumaramba
    Member

    Since it seems like switching to the modular SDK is the proper fix here I will convert this issue to a discussion. That will hopefully help with future issues like #1954

  22. locked and limited conversation to collaborators on Oct 27, 2022
  23. converted this issue into a discussion #1959 on Oct 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions