Using Firebase Realtime Database from Node - node.js

Anytime I run Firebase Realtime Database code from Node, using the Admin SDK, the process hangs. For example, I might have a node application deactivate.js:
const admin = require("firebase-admin");
// initialize app code...
admin.database().ref(`users/${userId}/active`).set(false)
I run with node deactivate.js. The user will be set to inactive, so that's good. But then the node process will just hang. I have to press ctrl-c to get back to a prompt.
Am I supposed to close connections or do something else in a Node application using Firebase? With Firebase Functions, I do have to return the promise generated from the above call. So, does Firebase Functions automatically handle closing whatever it is I now need to manually handle?

The way you deal with Cloud Functions is not at all the way you deal with standalone node processes. When using the Admin SDK to access Realtime Database in a standalone node process that must finish, do something like this instead to make sure the process exits when all work is complete:
admin.database().ref(`users/${userId}/active`).set(false)
.then(() => {
process.exit(0)
})
.catch((err) => {
console.error(err)
process.exit(1)
})

Related

Get all documents from a collection from Cloud Firestore

I need to get all documents from a collection in firestore.
I've been spending hours on trying it but with no results...
My app is under NodeJS 12.
This is what i've found :
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
const snapshot = db.collection('metrages').get();
snapshot.forEach((doc) => {
console.log(doc.id, '=>', doc.data());
});
But it says that "require is not defined".
Does anybody knows how to do that?
It appears that you are trying to execute this script inside a browser. This script needs to be executed in the terminal. i.e node main.js
Please note that node.js is a server-side Javascript execution environment that combines the V8 Javascript engine with a bunch of server-side libraries. require() is one such feature that node.js adds to the environment. So, when you run node in the terminal, you are running an environment that contains require(). require() is not a feature that is built into the browser. That is a specific feature of node.js, not of a browser. So, when you try to have the browser run your script, it does not have require(), hence the exception.

Dynamically passing dbName to mongoose.connect

For a MEAN app, I need to pass the dbName depending on the logged-in user. The flow of events is as follows.
User logs-in and gets authenticated using an auth specific REST-API.
Auth-API returns to Angular the user account data which includes the userSpecificDbName.
Thereafter, Angular makes all calls to the app's main REST-API. With all calls to the API, account data is passed and the API shd use the dbName from the account data in the following statement of app.js
mongoose.connect(uri, { dbName: <userSpecificDbName> })
.then( () => {
console.log('Connection to the Atlas Cluster is successful!')
})
.catch( (err) => console.error(err));
Is this possible? And how do I pass data in app.js for this purpose?
It is certainly possible to do that, Although keep in mind you would need to open and close connections per request to do that, which is not a regular pattern in Node.js
Normally you would connect to the database once and then fire queries. But in your case, you would disconnect every time after you've sent a response and reconnect and the beginning to the DB.
Alternatively, you could most probably do a useDb call as suggested in the following answer:
switching database with mongoose
That would help you switch the database.

Mongoose object refuses to save with .save()

To give some context: I have a Java client application that communicates high scores to a Node.js backend via sockets. All of those aspects are working correctly. The issue is that, when I run the object.save() method, it doesn't save the object in the db. It also doesn't throw any errors, and doesn't even console.log() like it's meant to.
Here is my code.
socket.on('setScore',function(data){
var workingScore = new Score(data);
console.log("WorkingScore:");
console.log(workingScore);
workingScore.save(function(err){
console.log("MADE IT THIS FAR");
if(err)
{console.log(err)}
else
{console.log("Saved!")}
})
});
None of the three console.log() handlers fire within the workingScore.save() callback.
When I create the server, I connect to my mongodb database, and this appears to work, as the mongod console shows a new connection when the server is started. The code for that is:
mongoose.createConnection('localhost','LeaderboardDB');
When I open mongo from terminal and do use LeaderboardDB then show collections nothing comes up.

Ensuring that only a single instance of a nodejs application is running

Is there an elegant way to ensure that only one instance of a nodejs app is running?
I tried to use pidlock npm, however, it seems that it works only on *nix systems.
Is it possible by using mutex?
Thanks
I've just found single-instance library which is intended to work on all platforms. I can confirm that it works well on Windows.
You can install it by npm i single-instance and you need to wrap your application code like this:
const SingleInstance = require('single-instance');
const locker = new SingleInstance('my-app-name');
locker.lock().then(() => {
// Your application code goes here
}).catch(err => {
// This block will be executed if the app is already running
console.log(err); // it will print out 'An application is already running'
});
If I understand its source code correctly, it implements the lock using a socket: if it can connect to a socket, then the application is already running. If it can't connect, then it creates the socket.

NodeJS/SailsJS app database block

Understand that NodeJS is a single thread process, but if I have to run a long process database process, do I need to start a web worker to do that?
For example, in a sails JS app, I can call database to create record, but if the database call take times to finish, it will block other user from access the database.
Below are a sample code i tried
var test = function(cb) {
for(i=0;i<10000;i++) {
Company.create({companyName:'Walter Jr'+i}).exec(cb);
}
}
test(function(err,result){
});
console.log("return to client");
return res.view('cargo/view',{
model:result
});
On first request, I see the return almost instant. But if I request it again, I will need to wait for all the records being entered before It will return me the view again.
What is the common practice for this kinda of blocking issue?
Node.js has non-blocking, asynchronous IO.
read the article below it will help you to restructure your code
http://hueniverse.com/2011/06/29/the-style-of-non-blocking/
Also start using Promises to help you avoid writing blocking IO.

Resources