node.jsfirebasefirebase-authenticationgoogle-cloud-functions

firebase.auth.user().onCreate won't deploy because of "TypeError: Cannot read properties of undefined (reading 'user')"


This is my code:

exports.createExample = functions.auth.user().onCreate((testUser) => {
  functions.logger.log("inside the auth trigger ", testUser.uid);
  return null;
});
  1. This trigger is working in production (I need to change some components inside the function - functions.logger.log is just sample code for troubleshooting)
  2. I have upgraded everything: firebase-functions is v6.3.2 and firebase-admin is v13.2.0
  3. I have checked and verified the following:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
  1. One suggestion was the admin.initializeApp() was the problem. I tried putting that inside the trigger function as suggested but same error
  2. This is apparently an error the CLI is calling on the deployment. I verified I am running 13.35.1
  3. I don't understand why, on deployment, the trigger would ever be defined? Seems like it would be undefined until such time as it was in production and a user was created in firebase auth.
  4. Full error is:
=== Deploying to 'sample_firebase_project'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> lint
> eslint .

✔  functions: Finished running predeploy script.
i  functions: preparing codebase default for deployment
i  functions: preparing codebase fix_overwrite_issue for deployment
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
i  artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
✔  artifactregistry: required API artifactregistry.googleapis.com is enabled
✔  functions: required API cloudbuild.googleapis.com is enabled
✔  functions: required API cloudfunctions.googleapis.com is enabled
⚠  functions: Runtime Node.js 18 will be deprecated on 2025-04-30 and will be decommissioned on 2025-10-31, after which you will not be able to deploy without upgrading. Consider upgrading now to avoid disruption. See https://cloud.google.com/functions/docs/runtime-support for full details on the lifecycle policy
i  functions: Loading and analyzing source code for codebase default to determine what to deploy
Serving at port 8689

TypeError: Cannot read properties of undefined (reading 'user')
    at Object.<anonymous> (/Users/test/AndroidStudioProjects/app/node_modules/firebase-tools/functions/index.js:35:47)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at loadModule (/Users/test/AndroidStudioProjects/app/node_modules/firebase-tools/functions/node_modules/firebase-functions/lib/runtime/loader.js:40:16)
    at loadStack (/Users/test/AndroidStudioProjects/app/node_modules/firebase-tools/functions/node_modules/firebase-functions/lib/runtime/loader.js:157:23)
    at /Users/testAndroidStudioProjects/app/node_modules/firebase-tools/functions/node_modules/firebase-functions/lib/bin/firebase-functions.js:56:56

NOTE: Both loader.js and firebase-functions.js are new and assumed to be current versions.

Any insights are appreciated


Solution

  • In September of 2024, Firebase Functions v6.0.0 was released. Importantly, as part of this major version update, the default import ("firebase-functions") was changed to import the 2nd Generation Firebase Functions SDK by default ("firebase-functions/v2"), instead of the 1st Generation Firebase Functions SDK ("firebase-functions/v1"). The new SDK version has moved many things around, so its recommended to read the 2nd gen upgrade documentation for details on differences.

    While many functions exist in the second generation Firebase Functions SDK (with different names), the analytics functions (from functions.analytics.event()) and basic authentication functions (from functions.auth.user()) do not have a second generation form. However, you can deploy 1st gen and 2nd gen Cloud Functions together from the same code base as long as you import the components from the right SDK version.


    To summarise the above, importing a functions object from "firebase-functions" now imports "firebase-functions/v2", not "firebase-functions/v1". This will often break the code you will find in code samples written before September 2024. The same applies for old projects and other StackOverflow threads from before the change was released.

    import * as functions from "firebase-functions";
    // is now equivalent to:
    import * as functions from "firebase-functions/v2";
    
    // but older code bases will instead expect:
    // import * as functions from "firebase-functions/v1";
    
    const functions = require("firebase-functions");
    // is now equivalent to:
    const functions = require("firebase-functions/v2");
    
    // but older code bases will instead expect:
    // const functions = require("firebase-functions/v1");
    

    In the code sample you provided, you must update your const functions = require(...) line to dismiss the error you are seeing from importing the wrong generation of the Firebase Functions SDK:

    const functions = require("firebase-functions/v1");
    const admin = require("firebase-admin");
    

    When ready to upgrade your other/future functions to 2nd Gen Cloud Functions, you would update your imports similar to what is shown below. As stated before, these imports can exist alongside older 1st gen functions, allowing you to update them over time or keep older functions while still able to write new ones.

    import {
      onDocumentWritten,
      Change,
      FirestoreEvent
    } from "firebase-functions/v2/firestore";
    import { onRequest } from "firebase-functions/v2/https";
    // OR
    const {
      onDocumentWritten,
      Change,
      FirestoreEvent
    } = require("firebase-functions/v2/firestore");
    const { onRequest } = require("firebase-functions/v2/https");
    

    While you could import a functions object from "firebase-functions" as before (even though it now imports "firebase-functions/v2"), the second generation SDK benefits from importing functions directly from their provider (firestore/https/etc.). This is so that optimisations can be done to improve cold-start and runtime performance of your Cloud Functions by discarding unnecessary code for functions you aren't utilising.