node.jsfirebasefirebase-authenticationgoogle-cloud-functions

Firebase Auth Cloud Function with Custom Claim Token Not Deploying


I'm trying to create a function that attaches a custom claim on to a specific user when they create an auth account through my sign in. When I try to push the function to Firebase cloud functions, I get this error:

firebase deploy --only functions

=== Deploying to 'project-name'...

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: 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...
+  functions: required API cloudfunctions.googleapis.com is enabled
+  artifactregistry: required API artifactregistry.googleapis.com is enabled
+  functions: required API cloudbuild.googleapis.com is enabled
i  functions: Loading and analyzing source code for codebase default to determine what to deploy  
Serving at port 8747

TypeError: Cannot read properties of undefined (reading 'user')
    at Object.<anonymous> (C:\Repos-local\project-vue-client\functions\index.js:10:50)
    at Module._compile (node:internal/modules/cjs/loader:1730:14)
    at Object..js (node:internal/modules/cjs/loader:1895:10)
    at Module.load (node:internal/modules/cjs/loader:1465:32)
    at Function._load (node:internal/modules/cjs/loader:1282:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
    at Module.require (node:internal/modules/cjs/loader:1487:12)
    at require (node:internal/modules/helpers:135:16)
    at loadModule (C:\Repos-local\project-vue-client\functions\node_modules\firebase-functions\lib\runtime\loader.js:40:16)

I've tried using the exact google documentation, and that doesn't work either. Here is my functions/index.js:

const functions = require('firebase-functions')
const { initializeApp } = require('firebase-admin/app');
const { getAuth } = require('firebase-admin/auth');

initializeApp();

// --- Function 1: Set Initial Claims for New Users ---
// This function automatically runs before a new Firebase Auth user is created.
// It sets the 'admin' custom claim to 'false' by default.
exports.setAdminPrivilegesFalse = functions.auth.user().onCreate(async user => {
  //Check if user meets role criteria
  if(user.email === 'example@email.com') {
    const customClaims = { admin: true };

    //Add the custom claims to the account
    try {
      await getAuth().setCustomUserClaims(user.uid, customClaims);
      //Log success
      console.log(`User ${user.email} now has admin privileges`);
    } catch (error) {
      console.log(error);
    }
  }
});

I'm trying to run firebase deploy --only functions. Here is the site I used for reference. Thank you in advance for any help!

https://firebase.google.com/docs/auth/admin/custom-claims#node.js_3

I tried running the following installs:

npm i firebase-tools
npm install firebase-admin@latest
npm install firebase-functions@latest
npm install firebase@latest
npm install -g firebase-tools
npm install

I checked and I have the blaze plan on firebase, and my project is connected to Firebase, auth works everywhere else.


Solution

  • Most likely you're using the latest version of the Firebase Admin SDK, and it prefers/requires your Cloud Functions to use 2nd generation syntax.

    Since I don't think the auth triggers have changed in quite some time, you might want to pin your firebase-functions dependency to version 5.1.1 (the last release before version 6.0.0 that made 2nd gen syntax the default) in your package.json:

    "dependencies": {
      ...
      "firebase-functions": "^5.1.1" // 👈 This pins the version
    },
    

    Alternatively (and probably better) is to use the latest firebase-functions and fix the import to import the v1 signature (based on Doug's answer that I linked below):

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

    Also see: