NodeJS GCP pubsub publishing error: t.topic(...).publish is not a function - node.js

I am trying to write data from my Node server to a pubsub topic that triggers a GCP Cloud Function. My code is more or less lifted straight from the GCP Pubsub tutorial.
However, I keep getting this error when I publish:
(node:60085) UnhandledPromiseRejectionWarning: TypeError: l.topic(...).publish is not a function
at /Users/kb/Documents/coding/maple/dist/server.bundle.js:100:1697
at Layer.handle [as handle_request] (/Users/kb/Documents/coding/maple/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/kb/Documents/coding/maple/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/kb/Documents/coding/maple/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/kb/Documents/coding/maple/node_modules/express/lib/router/layer.js:95:5)
at /Users/kb/Documents/coding/maple/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/Users/kb/Documents/coding/maple/node_modules/express/lib/router/index.js:335:12)
at next (/Users/kb/Documents/coding/maple/node_modules/express/lib/router/index.js:275:10)
at SendStream.error (/Users/kb/Documents/coding/maple/node_modules/serve-static/index.js:121:7)
at SendStream.emit (events.js:182:13)
I've confirmed that no messages are getting sent to my Pubsub topic, and that my GCP function isn't getting triggered.
Here is my code:
var processedData = processResultsData(data);
const dataBuffer = Buffer.from(processedData);
console.log("About to push to pubsub");
const messageId = await pubsub.topic(TOPIC_NAME).publish(dataBuffer);
console.log(`Message ${messageId} published.`);

The tutorial is correct for the current version of the node client libraries (0.24.1). My guess is that you have an old version of the client libraries installed. Check which version is in your package.json, and set it to "latest" or "0.24.1".

let message = {
id : `your-unique-id`,
data : [ {"key", "value"} , {"otherKey", "otherValue"} ]
}
const dataBuffer = Buffer.from(JSON.stringify(message));
const messageId = await pubsub.topic(topicName).publish(dataBuffer);
console.log('published : ', messageId );

Related

How to use more than one middleware in expressjs?

I am trying to use 2 middlewares for my route, auth.js and authAdmin.js which are in different folder.
var middleware = [auth, authAdmin]
router.get("/all_infor", middleware, userCtrl.getUsersAllInfor)
Official page of Expressjs defined the same way I did above but I am getting error:
F:\Mern projects\full_auth\node_modules\express\lib\router\route.js:202
throw new Error(msg);
^
Error: Route.get() requires a callback function but got a [object Object]
at Route.<computed> [as get] (F:\Mern
projects\full_auth\node_modules\express\lib\router\route.js:202:15)
at Function.proto.<computed> [as get] (F:\Mern
projects\full_auth\node_modules\express\lib\router\index.js:510:19)
at Object.<anonymous> (F:\Mern projects\full_auth\routes\userRouter.js:25:8)
can any one suggest how do I fix this? Thank You in advance.

Express URIError: Failed to decode param

I'm using next.js with a custom express server when the params of a request contains % it causes this error:
URIError: Failed to decode param '%%faker'
at decodeURIComponent (<anonymous>)
at decode_param (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\layer.js:172:12)
at Layer.match (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\layer.js:148:15)
at matchLayer (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:574:18)
at next (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:220:15)
at middleware (D:\ahmed\coding\react js\with-redux-app\node_modules\http-proxy-middleware\lib\index.js:43:7)
at Layer.handle [as handle_request] (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:317:13)
at D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:284:7
at Function.process_params (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:335:12)
at next (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:275:10)
at expressInit (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\middleware\init.js:40:5)
at Layer.handle [as handle_request] (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:317:13)
at D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:284:7
at Function.process_params (D:\ahmed\coding\react js\with-redux-app\node_modules\express\lib\router\index.js:335:12)
for example if the request is http://localhost:3000/summoner/eune/%%faker the error happens but if it's http://localhost:3000/summoner/eune/^^faker the ^^ gets encoded and the url becomes http://localhost:3000/summoner/eune/%5E%5Efaker and everything works perfectly.i could fix this error by following this answer Express handling URIError: Failed to decode param like so:
server.use((err, req, res, next) => {
if (err instanceof URIError) {
err.message = "Failed to decode param: " + req.url;
err.status = err.statusCode = 400;
console.log(err);
return res.redirect(`http://${req.get("Host")}${req.url}`);
// return app.render(req, res, "/_error");
}
});
return res.redirect(`http://${req.get("Host")}${req.url}`); this will redirect the user from http://localhost:3000/summoner/eune/%%faker to http://localhost:3000/summoner/eune/%25%25faker and if i use return app.render(req, res, "/_error"); it will send the default error page provided by next.js back to user but this is not what i want. I want to handle the % like ^.
so my questions are:
why the % doesn't get encoded to %25 and if there is a way to make it happen?
who is responsible for encoding the browser or express?
what is the best way to handle this error?
I'm using node v8.9.1, express ^4.16.3.
Please, make the answer detailed i'm a beginner developer.
Thanks for your time.
Like you pointed out, urls are percent-encoded and http://localhost:3000/summoner/eune/%%faker is just not valid as an url.
When you type an invalid url, most browsers are kind enough to change it to something valid, ex: http://localhost:3000/test test is automatically changed to http://localhost:3000/test%20test, but it's just a fallback to avoid too many errors.
In your case, % is not automatically changed to %25 because browsers cannot know when to substitute % and when to leave it. Ex: when you type %25%25faker, should this url be used as is or should it be replaced to %2525%2525faker ?
In summary: You must use valid urls at any point in time and not rely on browser kindness.

How to have service layer in loopback just like in other popular mvc frameworks?

I have started building an application in sailsjs but I decided to move it to loopback. From a j2ee/spring mvc background I was quickly up and running with sailsjs with some of my business logic in the api/service.
Unfortunatly I have not found a way to create those services on loopback. I am not talking about remote method. These services are not really tied to any model, they are on a layer above models. I have tried creating the following at server/service/DataModelService.js
module.exports = {
testMethod: function(){
return "Hello joseph"
},
testAnotherMethod: function(req,res){
//lots of other processing etc. Calling other services etc
res.send("something")
}
}
Created server/boo/routes.js with this following
module.exports = function(app){
app.get('/test', function(req, res){
res.send(DataModelService.testMethod());
});
}
but quickly got this reference error:
DataModelService is not defined
at /media/joseph/Data/Personal/tutorials/testingloopback/server /boot/routes.js:3:18
at Layer.handle [as handle_request] (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/layer.js:95:5)
at next (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/layer.js:95:5)
at /media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/index.js:330:12)
at next (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/loopback/node_modules/express/lib/router/index.js:271:10)
at cors (/media/joseph/Data/Personal/tutorials/testingloopback/node_modules/cors/lib/index.js:178:7)
at /media/joseph/Data/Personal/tutorials/testingloopback/node_modules /cors/lib/index.js:228:17
Can anyone show the right way of doing this ?
Thanks in advance
You need to require the module you're trying to access. Try this:
// server/boot/routes.js
var DataModelService = require('../service/DataModelService.js');
module.exports = function(app){
app.get('/test', function(req, res){
res.send(DataModelService.testMethod());
});
};
Without the require() call the variable is undefined. You can require this service (which is just a plain Node module) in any file in your application this way.

Kraken.js dust view engine

I am using Kraken.js with Dust as the default view engine. I get this error:
No default engine was specified and no extension was provided. at
new View
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/view.js:62:11)
at EventEmitter.render
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/application.js:569:12)
at ServerResponse.render
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/response.js:961:7)
at /home/zhiro/Desktop/kraken/krakil/controllers/index.js:14:13 at
Layer.handle [as handle_request]
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/router/layer.js:95:5)
at next
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request]
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/router/layer.js:95:5)
at
/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/router/index.js:277:22
at Function.process_params
(/home/zhiro/Desktop/kraken/krakil/node_modules/express/lib/router/index.js:330:12)
I see this error when I call res.render.
'use strict';
var IndexModel = require('../models/index');
module.exports = function (router) {
var model = new IndexModel();
router.get('/', function (req, res) {
res.render('index');
});
};
By default, Kraken doesn't configure a default view engine. The view engine tells Express how it should attempt to render files if it doesn't have a renderer explicitly defined for that file extension.
When you configure a new project using yo kraken, one of the questions it asks is what you would like your default view engine to be, but it sounds like you chose None on that step.
To set the default view engine, you simply pass it as part of the config object when instantiating Kraken. You can read about this in the Kraken README, under the heading Configuration-Based Express Settings:
Set the view engine property to the one of the view engines property names (see the section View Engine Configuration) to enable it for template rendering.
{
"express": {
[...]
"view engine": null, // set this to "dust"
[...]
}
}

Error with ntwitter module for node.js

I'm trying to build a Twitter streaming app using node.js and the ntwitter module, here's my code :
var app = require('express').createServer(),
twitter=require('ntwitter');
app.listen(3000);
var feed = new twitter({
consumer_key: 'MY KEY',
consumer_secret:'MY SECRET KEY',
access_tocken_key:'MY ACCESS TOCKEN KEY',
access_tocken_secret:'MY ACCESS TOCKEN SECRET'
});
feed.stream('statuses/filter',{track: ['love', 'hate']}, function(stream){
stream.on('data',function(tweet){
console.log(tweet.text);
});
});
But here's what I get :
events.js:74
throw TypeError('Uncaught, unspecified "error" event.');
^
TypeError: Uncaught, unspecified "error" event.
at TypeError (<anonymous>)
at EventEmitter.emit (events.js:74:15)
at ClientRequest.<anonymous> (/Users/maximeheckel/Documents/My_Repositories/nodetwitter/node_modules/ntwitter/lib/twitter.js:251:14)
at ClientRequest.EventEmitter.emit (events.js:95:17)
at HTTPParser.parserOnIncomingClient [as onIncoming] (http.js:1628:21)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:119:23)
at CleartextStream.socketOnData [as ondata] (http.js:1523:20)
at CleartextStream.read [as _read] (tls.js:470:10)
at CleartextStream.Readable.read (_stream_readable.js:294:10)
at EncryptedStream.write [as _write] (tls.js:344:25)
I don't understand why I'm stuck with that as I'm following very carefully a lot of tutorials. Even when I clone the authors project I'm still getting this error.
Hope you can help.
UPDATE : I added
stream.on('error', function(error, code) {
console.log("My error: " + error + ": " + code);
});
To my stream function and I'm getting a HTTP 401 error
Any ideas ?
Everything with your code looks fine except for the spelling of "token" in the parameters passed to the constructor for twitter. You need to change access_tocken_key to access_token_key and access_tocken_secret to access_token_secret. Your error (401) is an authentication issue; that change should hopefully result in ntwitter passing the correct user authentication details to the Twitter API.
I had the same problem and it was because my servers system clock had floated by six minutes. Usually, API's give you about a five minute margin of error.

Resources