How to run Pub-Sub functions in Firebase Functions shell - firebase

I'm unable to run my pub-sub triggers in local Cloud Functions Shell. I've created Cloud Functions in the following way:
export const sendNotifications = functions.pubsub.schedule('0 10 * * *').timeZone('Asia/Kolkata').onRun(async (context) => {
console.log('running sendNotificationForActivities');
await sendMessages();
return 0;
}
As mentioned here, I try to run firebase functions:shell from my system followed by:
> sendNotifications({data: new Buffer('{"hello":"world"}'), attributes: {foo: 'bar'}})
or
> sendNotifications({})
and other variants. Following is the error stack trace I received:
firebase > sendNotificationForActivities({})
'Successfully invoked function.'
firebase > ⚠ TypeError: Cannot read property 'params' of undefined
at cloudFunction (/Users/mayurdhurpate/code/pruoo_app/backend_admin/functions/node_modules/firebase-functions/lib/cloud-functions.js:109:38)
at Run (/Users/mayurdhurpate/.npm-global/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:458:20)
at /Users/mayurdhurpate/.npm-global/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:442:19
at Generator.next (<anonymous>)
at /Users/mayurdhurpate/.npm-global/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:7:71
at new Promise (<anonymous>)
at __awaiter (/Users/mayurdhurpate/.npm-global/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:3:12)
at Run (/Users/mayurdhurpate/.npm-global/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:435:12)
at /Users/mayurdhurpate/.npm-global/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:457:15
at Generator.next (<anonymous>)
⚠ Your function was killed because it raised an unhandled error.
I think I might be missing a required params field but I couldn't find the right way to enter the parameters. I'm using firebase-tools#7.1.1 on MacOS.

I have the same error.
The error is located in cloud-functions.js:117:28.
He is trying to access a key of context even if context does not exist.
I updated to the newest version but the error still persists.
As workaround I added this code at line 89 in cloud-functions.js: context = context || {};
This solves the error and I can use the firebase shell.
I hope this nasty hack helps.
Until Google fixes their code or updates the documentation.
Dominik

Related

node-oracledb on M1 Mac

I'm trying to connect to my university's Oracle DB. I wrote a simple backend that is working on my Windows machine but I can't get it working on my M1 Mac. You can find my repo here and here is the core of it,
const express = require('express');
const oracledb = require('oracledb');
if (process.platform === 'darwin') {
try {
console.log("Success");
oracledb.initOracleClient({libDir: process.env.HOME + '/Downloads/instantclient_19_8'});
} catch (err) {
console.log("Failure");
console.error('Whoops!');
console.error(err);
process.exit(1);
}
}
const dotenv = require('dotenv');
const app = express();
const PORT = 5000;
dotenv.config();
var cors = require('cors');
app.use(cors());
app.use(express.json());
app.listen(PORT, ()=>{console.log(`listen to port ${PORT}`);})
database_initialized = false
async function init_database() {
// The following should be wrapped in a try/catch
await oracledb.createPool({
user: process.env.USER_NAME,
password: process.env.DB_PASSWORD,
connectionString: process.env.CONNECTION_STRING
});
console.log("Successfully created connection pool");
database_initialized = true
}
app.get('/', (req,res) => {
res.send('Hello world!');
});
app.get('/get-customers', (req,res) => {
async function fetchDataCustomers(){
try {
const connection = await oracledb.getConnection();
oracledb.outFormat = oracledb.OUT_FORMAT_ARRAY;
const query = process.env.QUERY_STR;;
const result = await connection.execute(query);
console.log("Completed request");
try {
await connection.close();
}
catch (err) {
console.log("Encountered an error closing a connection in the connection pool.");
}
return result;
} catch (error) {
return error;
}
}
fetchDataCustomers().then(dbRes => {
res.send(dbRes);
})
.catch(err => {
res.send(err);
})
})
init_database();
I found someone who was nice enough to provide detailed instructions on using Rosetta to switch to the x64 version nvm, but my oracledb.createPool() function doesn't seems to be working on my M1 Mac (this works on my Windows machine). By that I mean the try block fails and drops to the catch block and prints "listen to port 5000" followed by repeatedly printing the console.log message. There are no other errors messages printed to the terminal.
On my M1 Mac, I follow the linked instructions and run nvm use intel and node -e 'console.log(process.arch)' to verify I'm using x64. On both machines, I can then run:
npm init -y
npm i --save express
npm i --save-dev nodemon dotenv oracledb cors
and node server.js to test the connection.
On my Windows machine, I connect and can then go on to check the endpoint I created (not included here but can be seen in the github repo I linked above). On my M1 Mac, I just get the message in the catch block telling me that an error was encountered. I want to be able to connect to an Oracle DB from my M1 Mac but it seems I don't yet have the skills to figure it out on my own. Any help would be appreciated.
Update:
After pulling oracledb.createPool() out of the try/catch I got the following:
listen to port 5000
(node:47913) UnhandledPromiseRejectionWarning: Error: DPI-1047: Cannot locate a 64-bit Oracle Client library: "dlopen(libclntsh.dylib, 0x0001): tried: 'libclntsh.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibclntsh.dylib' (no such file), '/usr/local/lib/libclntsh.dylib' (errno=62), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/libclntsh.dylib' (no such file), '/usr/lib/libclntsh.dylib' (no such file, not in dyld cache), 'libclntsh.dylib' (no such file), '/usr/local/lib/libclntsh.dylib' (errno=62), '/usr/lib/libclntsh.dylib' (no such file, not in dyld cache)". See https://oracle.github.io/node-oracledb/INSTALL.html for help
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have the 64-bit Oracle Instant Client Basic or Basic Light package libraries in
/usr/local/lib or set by calling oracledb.initOracleClient({libDir: "/my/instant_client_directory"}).
Oracle Instant Client can be downloaded from https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async init_database (/Users/my-name/workspaces/node-oracle-test-project/back-end/server.js:30:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:47913) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:47913) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I then re-ran npm install oracledb and I'm getting
oracledb ********************************************************************************
oracledb ** Node-oracledb 5.5.0 installed in Node.js 19.3.0 (darwin, x64)
oracledb **
oracledb ** To use node-oracledb:
oracledb ** - Oracle Client libraries (64-bit) must be available.
oracledb ** - Follow the installation instructions:
oracledb ** https://oracle.github.io/node-oracledb/INSTALL.html#instosx
oracledb ********************************************************************************
So I'm following the link and trying to find how to install Oracle Client libraries.
I'm following the instructions here but I'm not sure how to proceed. I ran /Volumes/instantclient-basic-macos.x64-19.8.0.0.0dbru/install_ic.sh as it says but I'm not where to move instantclient_19_8 so that it's accessible. I tried moving instantclient_19_8 to /Users/brian but that didn't resolve the error message.
I found this and added the suggested conditional to my code. Getting a new error.
(node:51947) UnhandledPromiseRejectionWarning: Error: ORA-24415: Missing or null username.
at async init_database (/Users/brian/workspaces/node-oracle-test-project/back-end/server.js:42:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:51947) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:51947) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Is there a solution? Will I just resolve one error to be greeted by another? Am I just wasting my time?
After pulling oracledb.createPool() out of the try/catch I got the following:
listen to port 5000
(node:47913) UnhandledPromiseRejectionWarning: Error: DPI-1047: Cannot locate a 64-bit Oracle Client library: "dlopen(libclntsh.dylib, 0x0001): tried: 'libclntsh.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibclntsh.dylib' (no such file), '/usr/local/lib/libclntsh.dylib' (errno=62), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/libclntsh.dylib' (no such file), '/usr/lib/libclntsh.dylib' (no such file, not in dyld cache), 'libclntsh.dylib' (no such file), '/usr/local/lib/libclntsh.dylib' (errno=62), '/usr/lib/libclntsh.dylib' (no such file, not in dyld cache)". See https://oracle.github.io/node-oracledb/INSTALL.html for help
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have the 64-bit Oracle Instant Client Basic or Basic Light package libraries in
/usr/local/lib or set by calling oracledb.initOracleClient({libDir: "/my/instant_client_directory"}).
Oracle Instant Client can be downloaded from https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async init_database (/Users/my-name/workspaces/node-oracle-test-project/back-end/server.js:30:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:47913) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:47913) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I then re-ran npm install oracledb and I'm got
oracledb ********************************************************************************
oracledb ** Node-oracledb 5.5.0 installed in Node.js 19.3.0 (darwin, x64)
oracledb **
oracledb ** To use node-oracledb:
oracledb ** - Oracle Client libraries (64-bit) must be available.
oracledb ** - Follow the installation instructions:
oracledb ** https://oracle.github.io/node-oracledb/INSTALL.html#instosx
oracledb ********************************************************************************
I followed the instructions here to install Instant Client but actually found this to easier to follow (because I stopped reading the doc once I thought I got what I needed). There is an issue with getting my credentials from my .env that I need to figure out but I'd consider that to be out of scope to my original post. This will work so long as the process.env values are hard coded. (I know. Fixing that is the next step.) I will update the GitHub repo I linked in the original post and hopefully others will find things easier than I did.
Update: The .env issue turned out to be an issue with where I was storing it. On my Windows machine I was able to put it in the parent directory (sibling to my .gitignore) but on my Mac I had to put it in the back-end directory.

Failed to generate manifest from function source: Error: Service account object must contain a string "private_key" property

I got this error after running npm run serve,
!! functions: Failed to load function definition from source: FirebaseError: Failed to load function definition from source: Failed to generate manifest from function source: Error: Service account object must contain a string "private_key" property.
Heres the screenshot of the logs
it seems service account issue heres my initialization
admin.initializeApp({ credential: admin.credential.applicationDefault(), });
i found the solution by commenting all of my codes , then theres new errors says , index.js not found , since im using typescript , and then i realised that im running the firebase deploy functions command using the wrong lib folder generated by typescript,
thats why i got these 2 erros:
Failed to generate manifest from function source: Error: Service account object must contain a string "private_key" property.
RangeError: Maximum call stack size exceeded.

I am getting error while deploying google cloud functions. Error - 'Invalid contents in the credentials file'

I am getting error while deploying google cloud function - with firebase (earlier it was working fine but suddenly this error started coming so I deleted the whole folder and did the process again but still not resolved)
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
.
.
.
Console
✔ functions: Finished running predeploy script.
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
Error: Error occurred while parsing your function triggers.
Error: Invalid contents in the credentials file
at FirebaseAppError.FirebaseError [as constructor] (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseAppError (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/utils/error.js:123:28)
at credentialFromFile (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/auth/credential.js:342:11)
at new ApplicationDefaultCredential (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/auth/credential.js:307:32)
at FirebaseNamespaceInternals.initializeApp (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/firebase-namespace.js:61:34)
at FirebaseNamespace.initializeApp (/Users/shayana/Documents/calleWork/calle/functions/node_modules/firebase-admin/lib/firebase-namespace.js:408:30)
at Object.<anonymous> (/Users/shayana/Documents/calleWork/calle/functions/index.js:14:7)
at Module._compile (internal/modules/cjs/loader.js:936:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
Based on what you've explained, and since the error you've received is about lack of credential, I really doubt that it has something to do with the function itself.
I can suggest two thing:
First: Update firebase-admin package,
Second: Set the service account and GOOGLE_APPLICATION_CREDENTIALS variable and initialize SDK explicitly following this procedure

failed to create function error because of name being too long

While deploying my code I get the following error:
⚠ functions: failed to create function tests-testV2RefreshPodcast-testNewEpisodeMetadata
...
Functions deploy had errors. To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.
my code looks like this:
exports.testNewEpisodeMetadata = functions.database.ref(testPath.getNewEpisodeScenarioTrigger()).onUpdate(() => {
return Promise.all([])
})
Found out that it was because of a name size limit. Heres a valid path:
✔ functions[tests-testV2RefreshPodcast-testNewEpMeta]: Successful create operation.
Notice how I changed the name testNewEpisodeMetadata to testNewEpMeta

Firebase Cloud Functions Shell not executing write operations on realtime database

Since a few days I am not able to test cloud functions locally anymore, as all write functions are not executed and nothing is returned, consequently the function hangs and eventually stops with a timeout.
Example function:
import { database as dbEvent } from "firebase-functions";
export default dbEvent.ref("/tariffs/removeHistory").onCreate((event: any) => {
console.log("START");
const bikesHistoryRef = event.data.adminRef.parent.parent.child("bikesHistory");
return bikesHistoryRef.set(null).then((res) => console.log("Delete done", res));
});
Result:
firebase > removeBikeHistory("test")
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: START
firebase >
firebase > info: Execution took 61023 ms, finished with status: 'timeout'
info: Execution took 49694 ms, finished with status: 'crash'
Any suggestion what is wrong? This happens with all my cloud functions, and when I deploy them it works.
I have tried with:
firebase-admin#5.5.1
firebase-functions#0.7.3
firebase-tools#3.15.4 (-g)
and
firebase-admin#5.6.0
firebase-functions#0.7.5
firebase-tools#3.16.0 (-g)
EDIT:
After enabling logging I get the following errors:
info: 0: onDisconnectEvents
info: p:0: Making a connection attempt
info: p:0: Failed to get token: Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: invalid_grant (Bad Request)". There are two likely causes: (1) your server time is not properly synced or (2) your certificate key file has been revoked. To solve (1), re-sync the time on your server. To solve (2), make sure the key ID for your key file is still present at https://console.firebase.google.com/iam-admin/serviceaccounts/project. If not, generate a new key file at https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk.
p:0: data client disconnected
info: p:0: Trying to reconnect in 1283.8299240003184ms
0: onDisconnectEvents
I have actually seen this error when I installed an older firebase-function/admin version, but thought it got fixed by installing the newer version. How can I fix it?
I found the solution in this bug report:
https://github.com/firebase/firebase-functions/issues/135
I have deleted the following file, now my cloud functions work locally again:
rm ~/.config/gcloud/application_default_credentials.json

Resources