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).
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
}
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.