I have firebase project that has few cloud functions. Some of them sends push notifications to the users. Before deploying any function, I develop it using the nodeJS on my local environment with standalone nodejs project.
However today I noticed that the function execution gets stuck after I try to send a push notification to even a single user. I mean to say the cursor does not return after I hit the node test.js and the execution never stops. I need to do ctrl + z in order to end the execution. However I get the push notification.
My code:
async function sendTest() {
await admin.messaging().sendToDevice(token, payload);
console.debug('Message Sent'); // this line gets printed instantly but execution continues
}
The following is also a similar code but it also doesn't end the execution even after printing the debug. statement.
async function sendTest() {
var notificationPersonalPromises = []
notificationPersonalPromises.push(admin.messaging().sendToDevice(token, payload));
await Promise.all(notificationPersonalPromises);
console.debug('Message Sent'); // this line gets printed instantly but execution continues
}
In both the above cases, I get the notification in couple of seconds and the debug gets printed instantly. If I comment out the push notification code then everything works fine. Please help...
The following image shows how the functions never ends the cursor keeps waiting...
Thanks
Make sure that your cloud function have a retunr. Even if you don't return anything. You can also return your last promise like:
async function sendTest() {
return admin.messaging().sendToDevice(token, payload);
}
or just an empty return like here:
async function sendTest() {
await admin.messaging().sendToDevice(token, payload);
console.debug('Message Sent'); // this line gets printed instantly but execution continues
return
}
Related
I am working with MySQL server, building a NodeJS server.
SomeWhere in the code I have async code that is not waiting, I believe its has something to do with the forEach function.
Is there anything wrong with my implementation of my next function:
async addResponsesToTasks(input, response, isFromCache) {
if (!isFromCache) {
this.saveResponseToCache(input, response);
}
console.log("===7===");
await response.forEach(async (pokemon) => {
console.log("===8===", pokemon);
await this.addTaskToFile(pokemon, false);
console.log("===13===");
});
return true;
}
And this is the output shows that it is not waiting for creation and save in the DB to finish, and jump to do some other things:
Prints of the output - can see 10,12,13,14,15 and only then 11
Hope you could maybe spot what I am missing.
Thanks in advance!
What's happening here is more of a JavaScript thing than a Sequelize thing.
The await is being applied to the lines of code that follow Item.create() inside of this function, but outer functions are continuing to execute.
console.log('9')
saveTaskToDb(task)
console.log('12')
In this code, '12' is going to get logged out before your '11', because this outer code is going to continue to execute, even if the code in saveTaskToDb is awaiting the resolution of the create() method.
To solve this, you'll either need to move all of your asynchronous code into the same code block, or you'll need to return your own promise in the saveTaskToDb function, and await saveTaskToDb.
So Solution was not using forEach, rather using for of loop like that:
async addResponsesToTasks(input, response, isFromCache) {
if (!isFromCache) {
this.saveResponseToCache(input, response);
}
for (const pokemon of response) {
await this.addTaskToFile(pokemon, false);
}
return true;
}
Based on this question: Using async/await with a forEach loop
I am using firebase functions Database Triggers.
My Function :
exports.function_name = functions.database
.ref("/transact/{entry_type}/{id1}/{id2}/trigger_cross_entry_function")
.onCreate((data, context) => {
console.log("trigger_cross_entry_function value", data.val());
if (data.val() == true) {
console.log("Function Calling parent data");
return data.ref.parent.once('value').then(function(snapshot){
}, function(error) {
// The Promise was rejected.
console.error("THIS IS THE ERROR:"+error);
});
} else {
console.log("Function Returned");
return 0;
}
});
Whenever I want to trigger this function I put trigger_cross_entry_function into that partcular path from the Mobile App. Everything works fine and function is called as expected.
After sometime If I again try to do the same thing it gives me
Function execution took 16 ms, finished with status: 'connection error'
If I restart the function than it again works perfectly.
and If I trigger it continously than it has no issue.
But once I keep it idle and try to trigger it
again after sometime, it gives me this error.
And I am using Firebase Pay as you go Plan.
Also, as you can see I am returning all the promises correctly and function is being triggered everytime but It doesnt go into the function. it just exit with connection error.
What might be the cause for this ? I have a spent a day finding this.
Experiencing the same issue. Looks like Google changed the status of the service to down
https://status.firebase.google.com/incident/Functions/18046
https://status.firebase.google.com/
So most likely the Google side problem.
I'm developing an app using Firebase as BaaS.
I'm having time problems when I'm uploading an image (with 90KB or less) and triggering a Cloud Function.
My trigger starts when upload ends:
exports.uploadControl = functions.storage.object().onFinalize((req, res) => {
uploadControl.handler(req, res);
return 0;
});
And, inside uploadControl, i have:
return mkdirp(tempLocalDir).then(() => {
console.log('1. mkDirp - OK!');
console.log('2. Download starts...');
return bucket.file(filePath).download();
}).then((content) => {
console.log('3. Download ends');
return 0;
});
This code works fine, but the problem is the time spent between step 2 and 3...
It takes 24 sec or more.
How to solve this? Is there any code problem? Or is there a Firebase setting to solve it?
Tks.
Two things wrong here:
The onFinalize() callback doesn't receive res and req objects like HTTP triggers do. It receives object metadata as the first argument. Read the documentation for details.
background triggers like this one must return a promise when all the work is complete. Otherwise Cloud Functions will shut down the work prematurely, as it has no idea when it's finished. If you want to kick off all that work from another function, it should be returning that promise.
-
exports.uploadControl = functions.storage.object().onFinalize(object => {
return uploadControl.handler(object);
});
I'm new to JS and trying cucumber js for the first time
This is how my step defn looks like:
Pseudocodes
Given("I launch Google.com", async (){
await Launch.launchGoogle():
})
When("I enter search text cucumber js", async (){
await Launch.searchCucumber():
})
This is how my Launch.js looks like:
module.exports launchGoogle= async function() {
await driver.get("www.google.com"):
}
module.exports searchCucumber = async function(){
await driver.findElement(By.name("q")).sendKeys("cucumber");
}
In this case, when I run the feature with 2 steps, I get ELIFECYCLE ERR at the end of first step.
When I remove the await in the step definitions, it runs fine. But, the console displays as 2 steps passed even before the chrome browser is launched. That is, it fires the Given and When steps and shows the result even as the code in Launch.js is still executing.
Pls help how to solve this?
I just figured out that the default step timeout is 5000ms. Since, launching the browser and hitting the URL was taking more than that, it was failing. i just increased the step timeout to 30000ms and it works fine.
As I understand, the differences between process.nextTick() and setImmediate() are the followings:
callbacks scheduled by process.nextTick() will ALL be executed before entering the next event loop, while callbacks scheduled by setImmediate() will only be executed ONE per event loop.
Base on the characteristics stated above, it can be said that: recursive call of process.nextTick() can cause the program to hang up, while recursive call of setImmediate() will not.
Then I've written some testing code to verify the statements above, here is my code:
process.nextTick(function() {
console.log('nextTick1');
});
process.nextTick(function() {
console.log('nextTick2');
});
setImmediate(function() {
console.log('setImmediate1');
process.nextTick(function() {
console.log('nextTick3');
});
});
setImmediate(function() {
console.log('setImmediate2');
});
My expected result should be
nextTick1, nextTick2, setImmediate1, nextTick3, setImmediate2
, but what I actually got is
nextTick1, nextTick2, setImmediate1, setImmedate2, nextTick3
Then I've run another test to study the behavior of setImmediate():
//the following code is using express as the framework
app.get('/test', function (req, res) {
res.end('The server is responding.');
});
app.get('/nexttick', function (req, res) {
function callback() {
process.nextTick(callback);
}
callback();
res.end('nextTick');
});
app.get('/setimmediate', function (req, res) {
function callback() {
setImmediate(callback);
}
callback();
res.end('setImmediate');
});
Step1: I accessed http://localhost:3000/nexttick on my browser and I got the text nexttick.
Step2: I accessed http://localhost:3000/test to test if my server is still responding to requests, and I didn't get any response, the browser kept waiting for response. This is nothing surprising because the recursive call of process.nextTick() had hanged up the server.
Step3: I restarted my server.
Step4: I accessed http://localhost:3000/setimmediate and got the text setimmediate
Step5: I accessed http://localhost:3000/test again to test if my server is still responding. And the result is as the same as Step2, I didn't get any response and the browser kept waiting for response.
This means the behavior of process.nextTick() and setImmediate() is pretty much the same but as I know they are not.
I was wondering why is this happening or have I misunderstood sth. Thank you.
P.S. I am running Node v0.12.7 under Windows 10.
Actually your test results looks ok (I only refer to the first test).
Your comments "setImmediate() will only be executed ONE per event loop." is wrong, See https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg
and thats the reason you don't understand the first test results.
Basically process.nextTick will put your function at the end of the current event loop while setImmediate will put it at the next event loop.
But executing multiple setImmediate is ok and they will all go to that same next event loop.
In
setImmediate(function() {
console.log('setImmediate1');
process.nextTick(function() {
console.log('nextTick3');
});
});
setImmediate(function() {
console.log('setImmediate2');
});
Basically you have put 2 function sthat will be invoked in next event loop, and in one of them you put another nextTick which will be invoked at the end of that same cycle but at the end of that same cycle.
So it will first invoke those 2 setImmediate and than the nextTick that was called in the first.