node.jstypescriptfirebasegoogle-cloud-platformgoogle-cloud-functions

What is the Response type of onRequest from firebase-functions/v2/https?


I am writing a simple code for Firebase Functions v2 in Node.js/TypeScript. I am struggling with the type definition of Response.

According to documentation, HttpsFunction should be compatible to Express Request and Response objects. Still, I am getting a type error message that HttpsFunction/Response is not compatible to Express/Response.

Is there a type definition for Response in firebase-functions/https? Could it be a compatibility issue of @types/express with firebase-functions (see package.json).

enter image description here

index.ts

import { onRequest } from 'firebase-functions/v2/https'; // Handle HTTP requests.
import type { HttpsFunction, Request } from 'firebase-functions/https';
import type { Response } from 'express';

import { geocodeRequest } from './geocode';

// Import the Google Maps Services client for making API requests.
import { Client } from '@googlemaps/google-maps-services-js';

// Instantiate the client.
const client = new Client({});

// API endpoint to handle geocoding requests.
export const geocode: HttpsFunction = onRequest(async (request: Request, response: Response) => {
  await geocodeRequest(request, response, client);
});

./gecode/index.ts

import type { Request } from 'firebase-functions/https';
import type { Response } from 'express';

import * as url from 'url'; // utilities for URL resolution and parsing.

import { type Client } from '@googlemaps/google-maps-services-js';

export const geocodeRequest = async (request: Request, response: Response, client: Client) => {
  try {
    // extract query parameters from a URL with a default value to handle undefined cases.
    const { city = '' } = url.parse(request.url, true).query;

    if (!city) {
      return response.status(400).json({ error: 'No city provided' });
    }

    const geocodingResponse = await client.geocode({
      params: {
        address: city.toString(), // ensure city is a string.
        key: process.env.GOOGLE_MAPS_API_KEY!,
      },
      timeout: 1000,
    });

    // if the location data is not found, send a 404 status code and a message.
    if (
      !geocodingResponse ||
      !geocodingResponse.data ||
      geocodingResponse.data.status === 'ZERO_RESULTS'
    ) {
      return response.status(404).json({ error: 'No location data available for city' });
    }

    // send geocoding results as a JSON response.
    return response.json(geocodingResponse.data);
  } catch (error) {
    console.error('Geocoding error:', error);
    return response.status(500).json({
      error: 'An error occurred while processing the geocoding request',
    });
  }
};

package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "version": "1.0.0",
  "scripts": {
    "build": "tsc",
    "build:watch": "tsc --watch",
    "serve": "npm run build && firebase emulators:start --only functions",
    "serve:watch": "npm run build:watch | firebase emulators:start --only functions",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "22"
  },
  "main": "lib/index.js",
  "dependencies": {
    "@googlemaps/google-maps-services-js": "^3.4.0",
    "firebase-admin": "^12.6.0",
    "firebase-functions": "^6.0.1",
    "url": "^0.11.4"
  },
  "devDependencies": {
    "@types/express": "^5.0.0",
    "firebase-functions-test": "^3.1.0",
    "typescript": "^4.9.0"
  },
  "private": true
}

Solution

  • Firstly, firebase-functions currently takes a dependency on @types/express version 4.17.21. You are forcing that to 5.0.0, which could be a problem since it's a major version change. I suggest removing @types/express from your package.json altogether and take what Firebase gives you by default.

    Secondly, you should probably import Request from firebase-functions/v2/https.

    I have no problems when I do these two things.