// ===============================================================================
// Auth
// ===============================================================================
const admin = require('firebase-admin'); //what happens if i move this line
admin.initializeApp(); //and this line
module.exports = function(app) {
//to this line
//and this line?
app.post('/login', function(req, res) {
const token = req.body.token;
console.log('token sent: ' + token);
admin
.auth()
.verifyIdToken(token)
.then(result => {
console.log('verifyIdToken result: ' + result);
});
res.send({ valid: 'havent programmed this yet' });
});
};
Let's say I'm working with the above code. I am curious why it still runs if I place the first lines of code:
const admin = require('firebase-admin');
admin.initializeApp();
from the outside of the anonymous function that module.exports to inside of it? I am so confused! Is this function looking outside of its module to grab this scope, and what is the difference in declaring this admin const from within module.exports rather than outside of it?
To understand what is happening, you need to understand Javascript Closures and Module Pattern.
When the two lines are outside the module.exports, they are part of the global scope and hence visible to your module. This is because variables defined outside any function, block, or module scope have global scope inside the file.
When you move it inside the module, they become part of function/ module's scope and hence again visible.
You can read this old but relevant article to get a better understanding.
https://www.joezimjs.com/javascript/javascript-closures-and-the-module-pattern/
Related
My code is like below...
describe('The Home Page',() =>{
before(()=>{
cy.fixture('WorkHours').then(function(data){
this.xxx = data
cy.log(this.xxx.weekDate+'..One')
})
})
it( 'checkNavis',() =>{
cy.log(this.xxx.weekDate+'..two')
cy.visit('/')
Gets an error ....[Cypress Log]
why dose it not referring to global variable?
could not be synchronization problem since waiting for promises??
since xxx is a declared global, shouldn't be scope??
this is related but doesn't give me a clue to identify problem...
Cypress - Typescript - How can i make my fixture variables global?
In your tests or hooks you cannot access aliases using this.* using arrow functions.
This is most likely because when this is used in an arrow functions it will have the same value as the context in which the arrow function was created (ie. undefined). The classic function () has its own this which is has global access.
Another example of this behaviour is in mocha. It has a restriction on the use of arrow functions.
Instead try:
describe('The Home Page',() =>{
before(function() {
cy.fixture('WorkHours').then(function(data){
this.xxx = data
cy.log(this.xxx.weekDate+'..One')
})
})
it('checkNavis', function() {
cy.log(this.xxx.weekDate + '..two')
cy.visit('/')
I'm having troubles with making a variable within a function global. This would work outside of the app.post('/init...) below
Here is my code:
const cloudlyn = require ('cloudlyn/demon')
app.post('/init', function(req, res){
cloudlyn.fly(customList, function(err, demonid){
if (err){
console.log(err)
}if (demonid){
console.log(demonid)
// everything works until this point.
userDemonid = demonid
// the problem is raising this variable to global scope.
// I understand not using const, var or let helps accomplish this
}
});
// then I have another function that needs this demonid.
// Notice that this is within the same app.post('/init'...)
const migrateCloudlyn = cloudlyn.migrate({
// I am trying to access the variable userDemonid
demonid = userDemonid,
plan = basePlan
}
});
The variable userDemonid is somewhat not available globally, any idea why this is so?
What am I doing wrongly?
You can use cookies or sub pages. Or debug function priority. "require()" function a interpreter. If defined a global function in 'cloudlyn/demon' it name is not your defined address. You can not import js code on DOM runtime. Try to access "cloudlyn.globalfoo".
With firebase you can write cloud functions in multiple files.
I have two functions, named "function1" and "function2", located in two separate files.
File: function1.js
const functions = require('firebase-functions');//This will be executed regardless of the function called
exports.function1 = functions.https.onRequest((request, response) => {
// ...
});
File: function2.js
const functions = require('firebase-functions');//This will be executed regardless of the function called
const admin = require('firebase-admin');//This will be executed regardless of the function called
exports.function2 = functions.https.onRequest((request, response) => {
// ...
});
Now I use index.js to export these files as shown here.
File: index.js
const function1 = require('./function1');
const function2 = require('./function2');
exports.function1 = function1.function1;
exports.function2 = function2.function2;
When I execute function1 I can access the "admin" variable from function2.
The obvious fix for this is to not declare the variable on the global scope.
Modified File: function2.js
const functions = require('firebase-functions');//This will be executed regardless of the function called
exports.function2 = functions.https.onRequest((request, response) => {
const admin = require('firebase-admin');//This will only be executed when function2 is called
// ...
});
Now the "admin" variable is only initialized when I call function2 and not function1.
Cloud Functions often recycles the execution environment of a previous invocation.
If you declare a variable in global scope, its value can be reused in subsequent invocations without having to be recomputed.
But now the "admin" variable will not be reused in subsequent invocations because it was not declared in the global scope.
So my question is how can store the "admin" variable on the global scope(so that it could be reused for multiple instances), but not have it initialized when function1 is called?
What you're trying to do is not possible. By definition, two server instances cannot share memory. They are completely isolated from each other. Each function invocation runs isolated in its own instance, and two different functions can never reuse the same instance. You will have to accept that the global memory space for function1 will never be seen by function2.
Watch this video to learn more: https://www.youtube.com/watch?v=rCpKxpIMg6o
After some research the answer is to do lazy initialization of global variables.
If you initialize variables in global scope, the initialization code will always be executed via a cold start invocation, increasing your function's latency.
If some objects are not used in all code paths, consider initializing them lazily on demand:
File: function1.js
exports.function1 = functions.https.onRequest((request, response) => {
// ...
});
File: function2.js
exports.function2 = functions.https.onRequest((request, response) => {
admin = admin || require('firebase-admin');
// ...
});
Now I use index.js to export these files as shown here.
File: index.js
const functions = require('firebase-functions');
const admin;
const function1 = require('./function1');
const function2 = require('./function2');
exports.function1 = function1.function1;
exports.function2 = function2.function2;
This is particularly important if you define several functions in a single file or multiple files, and different functions use different variables.
Unless you use lazy initialization, you may waste resources on variables that are initialized but never used.
Let's say I have this express application and want to add a global variable at the top
import express from 'express';
const app = express();
// var globalScopeVariable = 123;
app.get('/', (req, res) => {
// home page
});
app.get('/create/:message', (req, res) => {
// add block
});
app.get('/add/:peerPort', (req, res) => {
// add peer
});
Would it be good practice to use 'var' or 'let' in this scenario?
In your case (Node.js), neither var nor let make a global scope variable; both will create a module-scope variable (accessible inside this module, but not in other modules). This may be what you want (in which case, let is generally preferred these days, and var should be consigned to history); but it case it isn't, the only way to make a true global scope variable is by direct assignment:
global.globalScopeVariable = 123;
If your variable can be reassigned, then use let otherwise use const. You don't have to bother about var anymore.
You can always consider the following powerful master rules around variable declaration in modern JavaScript.
Stop using var as soon as you can!
Use const whenever you can!
Use let only when you really have to!
For my user registration I have
const express = require ('express');
const userRouter = express.Router ();
userRouter.get ('/', function getUserList (req, res) {
let User = require ('../models').User;
User.find ({}, function (err, list) {
res.json (list);
});
});
userRouter.post ('/', function createUser (req, res) {
let User = require ('../models').User;
if (req.body.username && req.body.password)
User.create (req.body, function (err, user) {
res.json (user);
});
});
... 3 more functions with the same `let User` ...
module.exports = userRouter;
Here, I have to require the module models twice. I tried setting the User variable as a global variable up at the top of the program, like
const express = ..., userRouter = ...
var User = ...
However this User variable is still not accessible inside my callback functions.
Is requiring the User module multiple times the correct way to do this or am I missing something?
edit: Inside the callback functions, the User variable is undefined.
As #Doug mentioned, you should pass global to the user variable like this:
global.user = ...
This process essentially turns user into a globally accessible variable. You can read more about Node's global here to understand what it does as well as understand what it's implications are too: http://stackabuse.com/using-global-variables-in-node-js/
To #charloetfl ‘s point if it is just within the file, declaring it outside the callback or on top of the file should do. If we are talking about access across all modules and files within the project then adding it to the global object is the way to go about it in node as #doug and #andrewl mentioned.