0

I want to reduce my overhead on function calls, fix cold start and also don't want to load extra stuff that is not needed in specific function call scope.

Like I have multiple functions, even scheduler functions too. So const {onSchedule} = require("firebase-functions/v2/scheduler"); is not required for every function, but will load if I do at the start of the file, instead of each function's if block.

// index.ts
export const httpFn = functions.https.onRequest(async (request, response) => {
    await (await import('./fn/httpFn')).myFun(request, response)
})

According to this article, the above sample code can do just one import, while in my case I have multiple imports respective to the function.

So based on this answer and comment, I wrote my code something like this (as I have a few more functions, but for sample code here is my full index.js file)

"use strict";

// Reference: https://cloud.google.com/functions/docs/configuring/env-var
// to save the cold start (removing the overhead by polluting with extra load)
const calledFunctionName = process.env.FUNCTION_TARGET ||
    process.env.FUNCTION_NAME ||
    process.env.K_SERVICE;

// The Firebase Admin SDK
const {initializeApp} = require("firebase-admin/app");

if (calledFunctionName && calledFunctionName === "addCourseData") {
  const {addCourseData} = require("./my-functions/my-course-functions");
  const {onRequest, HttpsError} = require("firebase-functions/v2/https");
  const {getFirestore} = require("firebase-admin/firestore");

  initializeApp();
  const firestoreDB = getFirestore();

  // Take the email and adds an entry to Firestore with Course data
  exports.addCourseData = onRequest(async (request, response) => {
    return await addCourseData(HttpsError,
        firestoreDB, request, response);
  });
}

But somehow, when I deploy using command firebase --only functions:addCourseData deploy, I see Deploy complete! but can't see the function under the Functions in the Firebase console, so can't access it from the client side too.

So it seems, I'm missing something or making a mistake while implementing that approach. Kindly help!

NOTE: Before using this approach, the function addCourseData was working properly and tested many times from the client side. And for this approach, I only modified index.js, not the my-course-functions.js

eagle
  • 567
  • 1
  • 6
  • 24
  • 1
    Your if block names `addOTPData` but defines `addCourseData`. Linking this question with [this thread](https://stackoverflow.com/a/67839410/3068190) (notes regarding v2 functions - based on Cloud Run) and [this one](https://stackoverflow.com/a/66815121/3068190) (notes on lazy initialisation that will work with v2 functions) for additional information. – samthecodingman Aug 24 '23 at 12:50
  • Thanks for pointing out, that was a typo for the sample code! Also, I elaborated on my question more. According to your 2nd link (your comment), are you suggesting one function per file (so export call directly loads only one file with its respective imports per container) and `initializeApp()` in a separate file and using it where needed??? – eagle Aug 25 '23 at 03:03
  • 1
    Splitting the files like shown in that other thread is a just a strategy that doesn't rely on any environment variables like you are in your question. IIRC, You only want to pull from `FUNCTION_NAME` (which is deprecated) and `K_SERVICE` (the modern equivalent of `FUNCTION_NAME`). `FUNCTION_TARGET` has some other value (at least for v1 functions). I'm also pretty sure that none of these are populated during deployment of your function so your condition should be `if (!calledFunctionName || calledFunctionName === "addCourseData") { /* ... */ }`. – samthecodingman Aug 25 '23 at 03:49
  • Thanks! Now i tried `const calledFunctionName = process.env.K_SERVICE;` just this, still deploy went complete, but can't see the function under Firebase Functions. Is there any extra step to use `process.env.K_SERVICE`??? – eagle Aug 25 '23 at 04:24
  • Did you change the conditions? – samthecodingman Aug 25 '23 at 04:26
  • Yes, I did. Now somehow I'm getting this error `Could not create or update Cloud Run service addotpdata, Container Healthcheck failed. Revision 'addcoursedata-00001-nam' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information.` – eagle Aug 25 '23 at 09:27

1 Answers1

0

Answer is exactly as given here.

So the resulting index.js becomes like this

"use strict";

// NOTE: process.env.K_SERVICE returns the lower alphabets ONLY,
// instead of camelCase or names-with-hyphens
const calledFunctionName = process.env.K_SERVICE;

// The Firebase Admin SDK
const {initializeApp} = require("firebase-admin/app");

if (!calledFunctionName || calledFunctionName === "addCourseData".toLowerCase()) {
  const {addCourseData} = require("./my-functions/my-course-functions");
  const {onRequest, HttpsError} = require("firebase-functions/v2/https");
  const {getFirestore} = require("firebase-admin/firestore");

  initializeApp();
  const firestoreDB = getFirestore();

  // Take the email and adds an entry to Firestore with Course data
  exports.addCourseData = onRequest(async (request, response) => {
    return await addCourseData(HttpsError,
        firestoreDB, request, response);
  });
}
eagle
  • 567
  • 1
  • 6
  • 24