cloud functions - export from .TS to .JS index - node.js

My project cloud functions are built-in javascript and I've decided to slowly migrate it to typescript file by file.
I'm trying to export my onCall function from a TypeScript file on my index.js to firebase cloud functions but I keep receiving the following error into the terminal
"Error: Error parsing triggers: Cannot find module './business'" when trying to deploy and not being able to properly import the Typescript function into my index.js
index.js
const business = require('./business');
exports.business.processBusinessSignUp;
business.ts:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as api from "./api";
import { BusinessFirestoreModel } from "./ts models/business_firestore_model";
module.exports.processBusinessSignUp = functions.https.onCall((data, context) => {
const business_model = new BusinessFirestoreModel(data.fullName, data.businessName, data.email, data.address, data.phone, Date.now());
return signBusinessUp(business_model);
});
const signBusinessUp = async (business: BusinessFirestoreModel) => {
const firestoreRef = admin.firestore().collection('pending_business').doc();
return await api.callFirestoreSet(firestoreRef, business.toJSON());
}
Any ideas?
Thank you!

As Brian Burton said You need to transpile your TypeScript into regular JavaScript before deploying if you want to run Typescript natively On Firebase Cloud Function, if you want more information here is the official documentation

Related

Firebase import cannot be done outside modules

I'm going crazy over "writing stuff exactly what the documentation wants but came back with different outcome."
I'm trying to import firebase to my express.js API so the app can GET directly from the database.
// Initialize Firebase
const functions = require('firebase-functions');
import { initializeApp } from 'firebase/app';
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
... //some other code
I've looked for the solution at
https://firebase.google.com/docs/web/setup
and
SyntaxError: Cannot use import statement outside a module Firebase Functions
but seems like the problem is pretty different. The outcome still 'SyntaxError: Cannot use import statement outside a module.'
Can anyone explain what happened? Did I miss something?
The latest Firebase version is now using the ES6/modular syntax which in return will result in SyntaxError: Cannot use import statement outside a module. You have to add the "type": "module" on your package.json. This enables ES6 modules discovery. Also, When using "module" you also have to change all your require syntax to import syntax. Here's your sample code for reference:
import * as functions from "firebase-functions";
import { initializeApp } from 'firebase/app';
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
package.json
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"type": "module",
...
}
For more information, you may check out this documentations:
ECMAScript Modules
Upgrade from version 8 to the modular Web SDK

Firebase Cloud functions - Failed to load function definition from source: Restful Endpoints - Failed to add the endpoint defined

I am using firebase cloud functions with typescript in node 16.14.
My index.ts look like this:
import { FunctionParser } from "firebase-backend";
exports = new FunctionParser({rootPath: __dirname, exports,
verbose:true}).exports;
Here is the addEvent.endpoint.ts:
import { Request, Response } from "express";
import { Endpoint, RequestType } from "firebase-backend";
// import * as functions from "firebase-functions";
const fs = require('firebase-admin');
const serviceAccount = require('./key.json');
fs.initializeApp({
credential: fs.credential.cert(serviceAccount)
});
const db = fs.firestore();
export default new Endpoint(
"addEvent",
RequestType.POST,
(request: Request, response: Response) => {
const message = request.body["message"];
db.collection("events").doc("adkakjagjh").set("message", message);
return response.status(201).send({
message: message
});
}
)
I have the following file structure as below.
My cloud functions worked just recently but some change that I am not aware of has made them error out with the following error for just this 1 endpoint "addEvent.endpoint.ts": Error: Failed to load function definition from source: Failed to generate manifest from function source: Error: Restful Endpoints - Failed to add the endpoint defined in C:/Development/EventFeeder/Backend/Firebase/functions/lib/users/restful/addEvent.endpoint.js to the users Api.
How can I fix this issue?
I am not sure what I need to try because the error message is not that specific about the problem's root cause.
I did not find any post about this particular problem.
I try to run the functions with "npm run build && firebase emulators:start --only functions" and "firebase emulators:start"
The issue disappear when I remove the addEvent.endpoint.ts file
I was facing the same problem, and I figured out that you shouldn't initialize the app (initializeApp()) in each endpoint, just write it in the index.ts one time and everything will work as expected.

How import firebase cloud function config dynamically in NodeJS 14 with `type: module`? [ closed ]

I would like to achieve importing cloud function config dynamically but it won't working as expected.
import config from "firebase-functions";
It works ✔️
const {config} = await import('firebase-functions');
It won't work ❌
also tried the following but won't works.
import * as functions from "firebase-functions"; // function is already using as static import
or
const functions = await import('firebase-functions');
functions.config ❌// => undefined
functions.auth ✔️
functions.firestore ✔️
//and analytics, app, auth, database, firestore, handler, https, pubsub, remoteConfig, storage, testLab, logger ✔️
Am not getting a way to dynamically import the config import along with function.
Oh finaly it works.
const { default: functions} = await import('firebase-functions');
and
import functions from "firebase-functions";
giving functions.config

Initializing multiple connections to firebase are failing in Nodejs for firebase-admin NPM

I have the following code trying to connect to Firebase Realtime Database in NodeJS using the latest firebase-admin package (10.x):
import { database } from 'firebase-admin';
import { applicationDefault, initializeApp } from 'firebase-admin/app';
const app = initializeApp({
credential: applicationDefault(),
databaseURL: 'https://DATABASE_NAME.firebaseio.com'
}, 'xx');
const db = database(app);
The issue is that the database(app) call fails with following error:
TypeError: _this.ensureApp(...).database is not a function
I believe that my code is correct since I need the ability to connect to multiple databases...
Anybody knows what am I doing wrong?
The following import is incorrect:
import { database } from 'firebase-admin';
The correct modular import is:
import { getDatabase } from 'firebase-admin/database';
getDatabase()
Or, if using the old namespaced API:
import * as admin from 'firebase-admin'
admin.database()

Firebase getAuth() throws error getProvider of undefined but can access database

I have the following code running on a Node server.
import admin from 'firebase-admin';
import {getAuth} from 'firebase/auth';
class MyFirebase {
constructor() {
console.log("MyFirebase Constructor");
this.firebaseApp = admin.initializeApp({
credential: admin.credential.cert("PATH_TO_CERT/cert.json"),
databaseURL: "https://DATABASE_URL",
});
console.log("App name="+firebaseApp.name);
this.defaultAuth = getAuth(firebaseApp);
this.database = this.firebaseApp.database();
// database ref code here...
}
}
and it throws the following error:
return app.container.getProvider(name);
TypeError: Cannot read property 'getProvider' of undefined
If I remove "firebaseApp" from the getAuth(..) call I get this error:
No Firebase app '[DEFAULT'] has been created - call Firebase
App.initializeApp() (app/no-app)
However the "console.log("App Name...")" line produces:
App name=[DEFAULT]
So clearly a DEFAULT app has been created. Additionally if I remove the "getAuth..." call the database calls pulling data from the realtime database below it work just fine, which seem to imply the authentication worked properly because I can access data from the database.
What the heck is going on?
You are confusing Firebase Admin SDK (Node.js) with Firebase Javascript SDK. The former is for the back-end, while the latter is for the front-end. I understand your confusion because the front-end package/s are installable via NPM, although they are meant to be bundled with front-end code.
You can't do this:
import admin from 'firebase-admin' // back-end code
import { getAuth } from 'firebase/auth' // front-end code !!!
const adminApp = admin.initializeApp(...)
getAuth(adminApp) // TypeScript actually catches this error
/*
Argument of type 'App' is not assignable to parameter of type 'FirebaseApp'.
Property 'automaticDataCollectionEnabled' is missing in type 'App' but required in type 'FirebaseApp'.ts(2345)
app-public.d.ts(92, 5): 'automaticDataCollectionEnabled' is declared here.
const adminApp: admin.app.App
*/
If you are on the back-end, just use adminApp.auth() to get the Auth instance. If on the front-end, you need to call getAuth with the front-end Firebase App instance:
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
const app = initializeApp(...)
const auth = getAuth(app)
The new modular apis have a slightly different syntax. The following should still work if you wrap it in a class, but as long as you only do this once at the top of your express? server you shouldn't need to use a class.
Also, I'm using the require syntax but imports should work too depending on your setup.
//Import each function from the correct module.
const { initializeApp, applicationDefault } = require("firebase-admin/app");
const { getAuth } = require("firebase-admin/auth");
const { getDatabase } = require("firebase-admin/database");
const app = initializeApp({
credential: applicationDefault(), //Don't forget to export your configuration json https://firebase.google.com/docs/admin/setup
databaseURL: "https://DATABASE_URL",
});
const auth = getAuth(app)
const database = getDatabase(app)
It's not super well documented but you can find hints in the Admin SDK reference: https://firebase.google.com/docs/reference/admin/node/firebase-admin.auth
One tip: In VSCode you should see the a description of each function when you hover over them, if you have the import path formatted correctly.

Resources