The default Firebase app already exists. This means you called initializeApp() more than once - node.js

I am just starting cloud functions with firebase. Here is my first function.
import * as functions from 'firebase-functions';
import express from 'express';
import admin from "firebase-admin"
admin.initializeApp(functions.config())
console.log('Firebase Environment setup success')
const app1 = express()
app1.get("*", (request, response) => {
response.send("bar")
})
const foo = functions.https.onRequest(app1)
module.exports = {
foo
}
Everytime I run this code with the emulator suite with
firebase emulators:start --only functions
And I visit the url output on the console, I get the error:
! Error: The default Firebase app already exists. This means you
called initializeApp() more than once without providing an app name as
the second argument. In most cases you only need to call
initializeApp() once. But if you do want to initialize multiple apps,
pass a second argument to initializeApp() to give each app a unique
name.
at FirebaseAppError.FirebaseError [as constructor] (C:\Users\Business\PhpstormProjects\gantt-flexx\node-server\node_modules\firebase-admin\lib\utils\error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (C:\Users\Business\PhpstormProjects\gantt-flexx\node-server\node_modules\firebase-admin\lib\utils\error.js:88:28)
at new FirebaseAppError (C:\Users\Business\PhpstormProjects\gantt-flexx\node-server\node_modules\firebase-admin\lib\utils\error.js:122:28)
at FirebaseNamespaceInternals.initializeApp (C:\Users\Business\PhpstormProjects\gantt-flexx\node-server\node_modules\firebase-admin\lib\firebase-namespace.js:68:23)
at FirebaseNamespace.initializeApp (C:\Users\Business\PhpstormProjects\gantt-flexx\node-server\node_modules\firebase-admin\lib\firebase-namespace.js:392:30)
at Proxy. (C:\Users\Business\AppData\Roaming\npm\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:338:51)
at C:\Users\Business\AppData\Roaming\npm\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:641:30
at Generator.next ()
at fulfilled (C:\Users\Business\AppData\Roaming\npm\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:4:58)
at process._tickCallback (internal/process/next_tick.js:68:7) ! Your function was killed because it raised an unhandled error.

Related

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.

Error: getaddrinfo ENOTFOUND on Vercel with Next.JS and serverless-mysql

I am using Next.js and in the API side i have write a dummy code to get rows from my database with this library : serverless-mysql
I have followed the example on the documentation and on my computer this working very fine, I can connect to the database et get the rows. My Database is on my VPS not on my localhost.
But when i deploy my code on Vercel, and I try to access to /api/hello
In my vercel log I have this error :
[GET] /api/hello
{
error: Error: Error: getaddrinfo ENOTFOUND "**.***.**.**"
at connect (/var/task/node_modules/serverless-mysql/index.js:80:15)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Object.query (/var/task/node_modules/serverless-mysql/index.js:182:5)
at async excuteQuery (/var/task/.next/server/pages/api/hello.js:33:25)
at async handler (/var/task/.next/server/pages/api/hello.js:59:24)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:102:9)
at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:1064:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:951:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:222:32)
at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:1135:29)
}
(I have replaced the real Ip showed in the message by "** . *** . ** . **")
My database accept connection from outside because I can access to it on my computer.
I have also correctly configured the .env var in project settings.
Thank you very much for your help
You will need to set the environment variables both on your vercel dashboard and your nextjs app.
In your .env file
NEXT_PUBLIC_VERCEL_URL = "http://localhost:3000";
In your code, reference the variable
export const getBaseUrl = () => {
if (process.env.NODE_ENV === "development") {
return "http://localhost:3000";
}
return process.env.NEXT_PUBLIC_VERCEL_URL;
}
You can then execute the utility function anywhere in your code.
On vercel, set the environment variable to VERCEL_URL

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.

how to use firebase storage bucket node sdk

the code is super simple
const sharp = require('sharp');
const admin = require('firebase-admin');
const fecha = require('fecha');
admin.initializeApp({
serviceAccountId: '<service-account>.iam.gserviceaccount.com',
databaseURL: "<database-url>",
storageBucket: "<storage-bucket>",
projectId: "<project-id>"
});
const storage = admin.storage();
// console.log(storage.bucket().ref('/general/reviews/1/test.jpg'));
console.log(storage.ref('/general/reviews/1/file.txt').putString('casacasacasa'));
i put this code into a cloud function but it crashes
storage.bucket(...).ref is not a function at exports.madrid (/workspace/index.js:666:30) at process.nextTick (/layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:100:17) at process._tickCallback (internal/process/next_tick.js:61:11)
and if i uncomment the first line it goes
TypeError: storage.ref is not a function at exports.madrid (/workspace/index.js:666:21) at process.nextTick (/layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:100:17) at process._tickCallback (internal/process/next_tick.js:61:11)
i'm 100% the bucket exists and this very same code on the android sdk works fine...
what am i doing wrong?
Take care if you use firebase-admin for storage you have to follow the documentation : https://googleapis.dev/nodejs/storage/latest/
With firebase-admin the ref function is replace by file like this :
admin.storage().bucket().file(remotePath).save(buffer)

I just followed the step by step process on google cloud function tutorial , anyone know how to fix this? or the cause of the problem?

I only followed the step by step tutorial on google firebase
this is the link:
https://firebase.google.com/docs/functions/get-started?authuser=0
and then I get these on cmd
Function failed on loading user code. Error message: Code in file index.js can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: /user_code/index.js:9
exports.addMessage = functions.https.onRequest(async(req, res) => {
^
SyntaxError: Unexpected token (
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:549:28)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.require (module.js:504:17)
at require (internal/module.js:20:19)
at getUserFunction (/var/tmp/worker/worker.js:439:24)
Functions deploy had errors with the following functions:
addMessage
These are the codes on the tutorial.
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:pushId/original
exports.addMessage = functions.https.onRequest(async(req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into the Realtime Database using the Firebase Admin SDK.`enter code here`
const snapshot = await admin.database().ref('/messages').push({original:
original});
// Redirect with 303 SEE OTHER to the URL of the pushed object in the
Firebase console.
res.redirect(303, snapshot.ref.toString());
});
Looking at the code you posted compared to the code in the example, I think the problem is:
Your code:
exports.addMessage = functions.https.onRequest(async(req, res) => {
example code:
exports.addMessage = functions.https.onRequest(async (req, res) => {
Notice that in your code there is no "space" character after async. Async is a qualifier of a function that flags the function as asynchronous. See here for details of async.
The omission of the space changes the semantics. If I had to guess, the runtime would now be looking for a function that is called async. Please change your code to include a space.

Resources