Can not Find Module - node.js

I have made a custom skill in amazon alexa and when testing the Node js code in AWS as LAMBDA Function , it is giving following error :
{
"errorMessage": "Cannot find module '/var/task/index'",
"errorType": "Error",
"stackTrace": [
"Function.Module._load (module.js:417:25)",
"Module.require (module.js:497:17)",
"require (internal/module.js:20:19)"
]
}
Here is the Code, which is connecting to the firebase and updating its content
const firebase = require('firebase');
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false; //<---Important
var config = {
apiKey: 'AIzaSyBQJasmuj2yzlkuXFwJ5-wL2kt0UMQ2V18',
authDomain: 'deftdev-a2416.firebaseapp.com',
databaseURL: 'https://deftdev-a2416.firebaseio.com',
storageBucket: 'deftdev-a2416.appspot.com'
};
//firebase.initializeApp(firebaseConfig);
//const db = firebase.database();
if(firebase.apps.length == 0) { // <---Important!!! In lambda, it will cause double initialization.
firebase.initializeApp(config);
}
firebase.database().ref('rooms/' +'HPOQhC9smxUxSGhM1XlBtweiNDE3/'+'roomdetails/01/1/appliance/0/'+).update({
toggle:1
});
};

Just check the name of your entry point file name if it is Index.js , then give the same name in the AWS Lambda function entry point . This will help

For completeness when using things like serverless framework you can get a very similar error if you installed your node modules locally with a later version of node than AWS supports.
The solution is to make sure you use the same node/npm version as you are in Lambda when you do an npm i

Mostly it is because of the way zipping the files making the problem. Instead of zipping the root folder you have to select all files and zip it like below,
Please upload all files and folders including your node_modules folder if you have one,

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.

Firebase Functions: Upload Error: HTTP Error: 400, Unknown Error

I tried to deploy the server side of my Angular Universal SSR app to Firebase Functions, but ran into the error Upload Error: HTTP Error: 400, Unknown Error.
From what I understand, this error happens pretty often when the deployment is a huge file (in my case it's 438mb). The reason it's so big is because I'm deploying localized versions of my website so dist/browser and dist/server both have en, de, and fr directories with pretty much the same content. How can I solve this issue?
console output
=== Deploying to 'PROJECT_NAME'...
i deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint
+ functions: Finished running predeploy script.
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
+ functions: required API cloudfunctions.googleapis.com is enabled
i functions: preparing dist directory for uploading...
i functions: packaged dist (438.04 MB) for uploading
! functions: Upload Error: HTTP Error: 400, Unknown Error
Error: HTTP Error: 400, Unknown Error
index.js
const functions = require('firebase-functions');
// Increase readability in Cloud Logging
require("firebase-functions/lib/logger/compat");
const expressApp = require('./server/proxy').app();
exports.ssr = functions
.region('us-central1')
.runWith({})
.https
.onRequest(expressApp);
proxy.ts (which gets compiled to js and put into the dist/server folder)
import * as express from 'express';
import * as cookieParser from 'cookie-parser';
import { join } from 'path';
export function app() {
const server = express();
server.use(cookieParser());
const languages = ['en', 'de', 'fr'];
languages.forEach((locale) => {
const appServerModule = require(join(__dirname, locale, 'main.js'));
server.use(`/${locale}`, appServerModule.app(locale));
});
server.get('/(:locale(en|fr|de)/)?*', (req, res, next) => {
const { locale } = req.params;
let userLocale = (req.headers['accept-language'] || '').substring(0, 2);
if(!languages.includes(userLocale)) {
userLocale = 'en';
}
if (locale !== userLocale) {
res.redirect(userLocale + req.url);
}
});
return server;
}
function run() {
app().listen(4200, () => {
console.log(`Node Express server listening on http://localhost:4200`);
});
}
run();
I had the same problem with NextJS and firebase functions,
Here is my solution:
Remove node_modules and run npm i
Remove cache files, out or public builds
Check functions console registry from firebase panel (here you can check your serve status/logs)
I hope this could help to someone.
I decreased the size of my deployment, and it immediately fixed the issue. I would say you just have to optimize the files you have, or think about storing some files in another location other than the firebase functions codebase (perhaps firebase storage)
I had this issue and just was able to fix it. In my case I had deployed to firebase a number of times and with each deploy the upload directory got bigger and bigger. I ended up changing my hosting settings to only keep the last 3 deploys which ended up dropping my package size from around 170MB to 15MB once the previous deploys were deleted. For some reason with each deploy it would take in each previous deploy when trying to upload a new release which doesn't make sense to me.

Node modules with sub-directories: "Error parsing triggers: Cannot find module 'ibm-watson'"

I have a Firebase Cloud Function that calls IBM Watson to get a token. I'm updating it from the old username/password auth to the current IAM auth.
Here's the code from the IBM documentation:
const watson = require('ibm-watson');
const { IamAuthenticator } = require('ibm-watson/auth');
// to get an IAM Access Token
const authorization = new watson.AuthorizationV1({
authenticator: new IamAuthenticator({ apikey: 'fakekey-1234' }),
});
authorization.getToken(function (err, token) {
if (!token) {
console.log('error: ', err);
} else {
// Use your token here
}
});
When I run firebase deploy --only functions I get this error:
Error: Error parsing triggers: Cannot find module 'ibm-watson'
Require stack:
- /Users/TDK/LanguageTwo/functions/index.js
- /Users/TDK/.nvm/versions/node/v13.10.1/lib/node_modules/firebase-tools/lib/triggerParser.js
ibm-watson is installed in my /functions/node_modules directory:
I reinstalled ibm-watson, and for good measure I ran npm install in my functions directory. Plus I ran npm-check and updated all my node modules.
The specific line that causes the error is:
const watson = require('ibm-watson');
When I comment out that line the functions deploy without error. Unfortunately, the function doesn't run. :-)
This line does not cause the deploy error:
const { IamAuthenticator } = require('ibm-watson/auth');
I use IBM Watson in other Firebase Cloud Functions in the same index.js file. These lines from other functions don't cause deploy errors:
let TextToSpeechV1 = require('ibm-watson/text-to-speech/v1');
...
var LanguageTranslatorV3 = require('ibm-watson/language-translator/v3');
The problem seems to be that requiring the parent directory ibm-watson fails, but requiring the subdirectories of the parent directory works. Any suggestions?
This is as expected. If you take a look at the GitHub repo for ibm-watson - https://github.com/watson-developer-cloud/node-sdk - you will notice that there is no example requiring the top level library. This stops you from pulling in the full library, when you only need to pull in a small sub-component.

Error: The default Firebase app does not exist

I'm tryin to do a simple function about Reading Data Once. but I get error like this:
index.js
var firebase = require("firebase");
var config = {
apiKey: "some api key",
authDomain: "fitto-exercise.firebaseapp.com",
databaseURL: "https://fitto-exercise.firebaseio.com",
projectId: "fitto-exercise",
storageBucket: "fitto-exercise.appspot.com",
messagingSenderId: "some number"
};
firebase.initializeApp(config);
and the search.js is here:
var firebase = require('.');
var admin = require("firebase-admin");
var db = admin.database();
var ref = db.ref("exercises/exercise");
ref.once("58.967", function(data) {
console.log("Got it!");
});
index.js and search.js in the same directory
I'm still inexperienced about this stuff maybe there are some noob mistakes.
This is my database looks like:
A couple problems here. If you're trying to require() some other file, it needs to have an export defined. In index.js (if that's what you're trying to require), doesn't have an export.
I'd suggest using just a single file for now, until you get your most basic code to work.
Also, according to the API documentation for once(), the method accepts, as its first argument:
One of the following strings: "value", "child_added", "child_changed",
"child_removed", or "child_moved."
"58.967" isn't one of them, and I don't know what you were intending to do there. But you probably want to use "value" to get the value of a child in the database.

Retrieving a Firebase storage image link via Cloud Function

How do I retrieve the download links to stored images in Firebase via a cloud function?
I've tried all kinds of variations including the next one:
exports.getImgs = functions.https.onRequest((req, res) => {
var storage = require('#google-cloud/storage')();
var storageRef = storage.ref;
console.log(storageRef);
storageRef.child('users/user1/avatar.jpg').getDownloadURL().then(function(url) {
});
});
It annoyed me, so I will put the solution with a straight forward explanation to those who are looking for it.
1st, install GCD Storage using the firebase command line:
npm install --save #google-cloud/storage
Cloud function code:
const gcs = require('#google-cloud/storage')({keyFilename: 'service-account.json'});
const bucket = gcs.bucket('name-of-bucket.appspot.com');
const file = bucket.file('users/user1/avatar.jpg');
return file.getSignedUrl({
action: 'read',
expires: '03-09-2491'
}).then(signedUrls => {
console.log('signed URL', signedUrls[0]); // this will contain the picture's url
});
The name of your bucket can be found in the Firebase console under the Storage section.
The 'service-account.json' file can be created and downloaded from here:
https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk
And should be stored locally in your Firebase folder under the functions folder. (or other as long as change the path in the code above)
That's it.

Resources