What is the best way to invoke a user-defined function from within another custom cloud function located in my index.ts file?

In order to understand how Firebase will bill me for function invocations, I have set up a scenario with two functions: newUserFlow and addFriend. My intention is to test whether calling newUserFlow from within addFriend will register as 1 or 2 functions invoked in the Firebase Console's Cloud Functions Usage tab. However, I am encountering an error.

exports.newUserFlow = functions.https.onCall((data, context) => {
  return 'finished new user flow';
});

exports.addFriend = functions.https.onCall((data, context) => {
  console.log('addFriend: ');
  const promise = exports.newUserFlow(null, null)
  
  promise.then(async (outputVal: string) => { 
    console.log('addFriend_outputVal: ', outputVal)
    const uid1 = context?.auth?.uid;
    if (uid1) {
      var uid2: string;
      const docUID2 =  await admin.firestore().collection('users').where('username', '==', data.targetUser).get();
      const friendsColl = 'friends_' + uid1
      if (!docUID2.empty) {
        docUID2.forEach(doc => {
          uid2 = doc.get('uid').toString(); 
          if (uid2) {
            const docRef = admin.firestore().collection(friendsColl).doc();
            return docRef.set({
              friendUID: uid2,
              stat: 0, 
              createDate: admin.firestore.FieldValue.serverTimestamp(),
              modifiedDate: admin.firestore.FieldValue.serverTimestamp(),
            })
          }
          else {
            return console.log('addFriend_Error: Target uid is empty.');
          }
        })
      }
      else {      
        return console.log('addFriend_Error: Target user not found.');
      }
    }
    else {
      return console.log('Error: user is not authorized');
    }
  })

  promise.catch((outputVal: string) => {
    return console.log('addFriend_promisecatch')
  })
  
});

error Promises must be handled appropriately or explicitly marked as ignored with the void operator

Answer №1

Firstly, it's important to distinguish between a Cloud Function invocation and a regular JavaScript (or TypeScript) function invocation. Within a single Cloud Function invocation, you can call multiple JS functions without incurring additional costs per call. You're only billed for the additional time it takes to execute those functions.

Secondly, it's not usually recommended for one callable Cloud Function to invoke another callable Cloud Function. If you need two Cloud Functions to share some functionality, it's better to have them both call a shared JS function instead.


exports.cloudFunction1 = functions.https.onCall((data, context) => {
    sharedJsFunction()
});
exports.cloudFunction2 = functions.https.onCall((data, context) => {
    sharedJsFunction()
});

function sharedJsFunction() {
}

The error message regarding not returning a promise is separate from the above points. It's essential to understand how to correctly handle promises and ensure that your code returns a promise from the main Cloud Function that resolves with the data to send back to the client. Currently, your addFriend function isn't returning anything at all. Its return statements are only within the anonymous callback function async (outputVal: string) => {}, not at the top level of the function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Typescript: Creating a new type by filtering an interface for matching properties

Imagine you have an interface structured like this: interface endpoints { "/api/user/{id}": { get: operations["getUserGET"]; }; "/api/user/add": { put: operations["addUsingPUT"]; }; ... } Is it pos ...

Strategies for Handling Errors within Observable Subscriptions in Angular

While working with code from themes written in the latest Angular versions and doing research online, I've noticed that many developers neglect error handling when it comes to subscription. My question is: When is it necessary to handle errors in an ...

Using React with TypeScript: How to store a base64 encoded string in useState

How can I resolve the unknown type error when trying to save a base64 string to state in React? import React, {useState, useRef} from 'react'; const App: React.FC = () => { const [state, setState] = useState({country: '', firstNa ...

Transitioning from ng-repeat filter to Typescript

As I migrate my project from AngularJS to modern Angular 8, one of the steps is converting JavaScript code to TypeScript. During this process, I encountered a challenging issue with the `ng-repeat` filter feature. Initially, my HTML template looked like t ...

Guide to setting up Jest configuration for TypeScript

Currently utilizing nestjs. Before running all tests, it is necessary to execute migrations. Once all tests have been completed, the test schema needs to be cleared. If I utilize javascript setup files in test/config/setup.js within package.json, every ...

Mastering Angular: Accessing undefined properties (specifically 'push')

Currently, I am in the process of learning Angular and have encountered an issue while working on an assignment. The error message that I am facing is "Cannot read properties of undefined (reading 'push')." Despite knowing that this is a common e ...

Discovering the generic parameter types with union in TypescriptUncover the

I've been struggling with the code snippets below for a while. Can someone explain why e4 is defined as string and not String? type PropConstructor4<T = any> = { new(...args: any[]): (T & object) } | { (): T } type e4 = StringConstructor ext ...

Error message in TypeScript React: Unable to assign onClick to type 'IntrinsicAttributes'

I recently came across this code for a component: Feedback.tsx import React, { useState } from 'react'; import './Feedback.css'; import FeedbackButton from './FeedbackButton'; function Feedback() { const [isOpen, setIsOpe ...

Animating Chart.js inside an Angular mat-tab component

I have a situation where I'm displaying multiple charts within a mat-tab, but I'm experiencing an issue with the animation of data in the chart. animation: { duration: 1000, easing: 'easeOutQuart' } The a ...

Struggling with a TypeORM issue while attempting to generate a migration via the Command Line

Having some trouble using the TypeORM CLI to generate a migration. I followed the instructions, but when I run yarn run typeorm migration:generate, an error pops up: $ typeorm-ts-node-commonjs migration:generate /usr/bin/env: ‘node --require ts-node/regi ...

Is there a way to retrieve the status code from the HttpClient module in Angular?

Can you find out how to retrieve the status codes for all requests using the HttpClient method? callingAPI() { let headers = new HttpHeaders(); headers = headers.append('Content-Type', 'application/json'); headers = headers. ...

What is the best method for searching a string without considering uppercase or lowercase letters?

Here's a straightforward question I have: I need to search for a specific string match in a query. The code snippet is shown below: const test_name = 'ExAmPlE' const database_resources = await prisma.market.findMany({ where: { na ...

Creating a unique ngrx operator from scratch that modifies the source observable and outputs its type

I developed a custom operator called waitFor that is being used in my effects like this: public effect$: Observable<Action> = createEffect(() => { return this.actions$.pipe( ofType(myAction), waitFor<ReturnType<typeof myActio ...

Tips for synchronizing the display of a table with the server response in an Angular application

* Project I am currently working on a project that involves retrieving player data from a json server and displaying it in a standard table format with a paginator. * Issue The challenge I'm facing is ensuring that the table data is loaded before th ...

Unable to initialize metro server due to the error "attachToServer is not a valid function"

After following the instructions in the original documentation, I executed npx react-native init AwesomeProject without making any changes. However, when I try to run npx react-native start or yarn start, I encounter an error stating that attachToServer i ...

Having issues with ngx-Bootstrap 4 dropdown and navbar functionality in Angular 7

I've been attempting to integrate Bootstrap 4 into my Angular 7 project, but I'm facing issues where the styles seem to be overridden by Bootstrap styles. The navigation bar and dropdown box also don't seem to function properly. To add Boot ...

Is it possible to dynamically pass a component to a generic component in React?

Currently using Angular2+ and in need of passing a content component to a generic modal component. Which Component Should Pass the Content Component? openModal() { // open the modal component const modalRef = this.modalService.open(NgbdModalCompo ...

How can we exclude fields from JSON.stringify in type-graphql entities?

Utilizing https://github.com/MichalLytek/type-graphql for crafting our graphql schema has posed a challenge. When we serialize the TypeScript entity object, it does not adhere to the field annotations in our GQL entities, resulting in unwanted data leakage ...

How can we avoid excessive re-rendering of a child component in React when making changes to the parent's state?

In my React application, I am facing a situation where a parent component controls a state variable and sends it to a child component. The child component utilizes this state in its useEffect hook and at times modifies the parent's state. As a result, ...

Tips for invoking an asynchronous function within an if condition?

When trying to maintain variables in the background.js of a Chrome extension, I encountered difficulties that require me to reinitialize some global variables. Here is the code snippet (view fiddle) I am using to demonstrate the issue: var temp = null; ...