node-oracledb on M1 Mac - apple-m1

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.

Related

How to run Pub-Sub functions in Firebase Functions shell

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

Firebase Functions Error while deploying to emulator

I'm trying to start new Firebase Functions project using latest versions of packages.
I've followed this tutorial https://youtu.be/DYfP-UIKxH0:
Firebase login
Firebase init
Created functions project the same way as tutorial says
Uncommented index.ts content
After that I get this error:
Starting #google-cloud/functions-emulator
[2018-04-04T19:05:12.124Z] Parsing function triggers
[2018-04-04T19:05:12.404Z] Error while deploying to emulator: TypeError: Cannot read property 'call' of undefined
TypeError: Cannot read property 'call' of undefined
at Promise (/usr/local/lib/node_modules/firebase-tools/node_modules/#google-cloud/functions-emulator/src/client/rest-client.js:34:42)
at getService.then (/usr/local/lib/node_modules/firebase-tools/node_modules/#google-cloud/functions-emulator/src/client/rest-client.js:33:16)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
⚠ functions: Failed to emulate helloWorld
I have latest functions emulator *1.0.0-beta4.
All other libs are in latest versions...
I'm at point where I have no idea how to debug this better and how to resolve this
This error occurs if an existing process listens on port 5000. Double check if there's a process running, e.g. on Mac OS Sierra
sudo lsof -n -iTCP:5000 | grep LISTEN
Stop this process or run firebase on another port, e.g.
firebase -p 7777 serve --only functions
No need to reinstall packages. Error message is not helpful and we spent some time to find the root cause.
It turned out that it was due other app that was listening on port 5001!
Firebase serve stops with some weird message.
Just check as answer below if ports aren't busy

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

Meteor throws "Must throw non-empty error" on page load

So my Meteor project just crashes after a small ammount of time (2 seconds (maybe)). I get this error in the console and Meteor exits: (whole console output from meteor command)
[[[[[ /path/to/meteor/project ]]]]]
=> Started proxy.
=> Started MongoDB.
=> Started your app.
=> App running at: http://localhost:3000/
/home/user/.meteor/packages/meteor-tool/.1.1.9.42pmuo++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/fibers/future.js:259
throw new Error('Must throw non-empty error');
^
Error: Must throw non-empty error
at Object.Future.throw (/home/user/.meteor/packages/meteor-tool/.1.1.9.42pmuo++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/fibers/future.js:259:10)
at Extract.<anonymous> (/tools/fs/files.js:699:42)
at Extract.emit (events.js:117:20)
at DirWriter.<anonymous> (/home/user/.meteor/packages/meteor-tool/.1.1.9.42pmuo++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/tar/lib/extract.js:61:8)
at DirWriter.emit (events.js:117:20)
at FileWriter.<anonymous> (/home/user/.meteor/packages/meteor-tool/.1.1.9.42pmuo++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/fstream/lib/dir-writer.js:158:12)
at FileWriter.emit (events.js:117:20)
at WriteStream.<anonymous> (/home/user/.meteor/packages/meteor-tool/.1.1.9.42pmuo++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/fstream/lib/file-writer.js:50:47)
at WriteStream.emit (events.js:95:17)
at onwriteError (_stream_writable.js:239:10)
at onwrite (_stream_writable.js:257:5)
at WritableState.onwrite (_stream_writable.js:97:5)
at evalmachine.<anonymous>:1692:14
at Object.wrapper [as oncomplete] (evalmachine.<anonymous>:522:5)
Could it be an issue with available free space, or an error handling bug? This issue reports a similar case: https://github.com/meteor/meteor/issues/4178
You have not enought space for mongo.
Try to install mongo and then start its server with --smallfiles
Then tell meteor to start using the listening mongo.
MONGO_URL=mongodb://0.0.0.0:27017 meteor

Problems starting a freshly installed Mean Stack application

I'm trying to start a new mean stack application. However i only get this error when I'm running grunt to start the server:
[nodemon] v1.2.1
Running "watch" task
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node --debug server.js`
Waiting...
Debugger listening on port 5858
Mean app started on port 3000 (development) cluster.worker.id: 0
/Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:246
throw message;
^
TypeError: Cannot read property 'length' of undefined
at processResults (/Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1581:31)
at /Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1619:20
at /Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1157:7
at /Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1890:9
at Server.Base._callHandler (/Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:448:41)
at /Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:481:18
at MongoReply.parseBody (/Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
at null.<anonymous> (/Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:439:20)
at emit (events.js:107:17)
at null.<anonymous> (/Users/olehenrik/Sites/learn/mean_test2/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)
[nodemon] app crashed - waiting for file changes before starting...
Have any one encountered this before? Can't find too many other people who have encountered this before.
I was also facing the same error and this info solves it.
"Upgrade to 3.8.23. 3.8.22 introduced better compatibility with mongodb server 3.0 by upgrading to latest version of the driver." credit to vkarpov15 from mongoose Github thread.
What I did was I edit my package.json to upgrade mongoose to "3.8.23". After I edited the package.json I ran npm install and bower install(just to make sure) again and that solved the problem.

Resources