I am writing a function that accepts input from an API endpoint. But the problem is when I now want to insert the records into the database. Immediately I add the async before the function I get an eslint error of Parsing Error: Unexpected token =>. Because of this, I cannot deploy the function. Kindly also look at the attached screenshot
app.post("/c2b/confirm", async (req, res) => {
console.log("----------confirm-------------");
console.log(JSON.stringify(req.body));
const payment = admin.firestore().collection("payments").doc();
await payment.set(req.body);
res.status(200).json({"ResultCode": 0, "ResultDesc": "Success"});
});
exports.main = functions.https.onRequest(app);
It is a linter error.
Please, be sure you have these in your eslintrc:
{
"env": {
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 8
}
}
Related
I'm trying to add unit testing on a brand new strapi application. The official documentation is still in progress. So, until the documentation is being ready is there a way to add jest unit testing to strapi application ? i followed the approach in the v3 documentation with no luck.
There are quite a few changes from Strapi V3 to Strapi V4 when it comes to initializing a Strapi application's APIs. The most important changes are how Strapi populates the KOA routes, and how to make requests to the http server.
To populate the KOA routes use
await instance.server.mount();
instead of
await instance.app
.use(instance.router.routes()) // populate KOA routes
.use(instance.router.allowedMethods()); // populate KOA methods
instance.server = http.createServer(instance.app.callback());
To call the http server use
strapi.server.httpServer
instead of
strapi.server
You also need to use the new database configuration schema when defining your test database. You can use the following as an initial setup for your tests.
The following is an updated (and WIP) guide based on Strapi V3 Unit Testing guide.
First run
yarn add --dev jest supertest sqlite3
or
npm install --save-dev jest supertest sqlite3
Then add the following to your ./package.json scripts:
"scripts": {
// ...strapi scripts
"test": "jest --forceExit --detectOpenHandles", //add
"watch": "yarn test --watch", // optional
}
Then add the following files:
./jest.config.js
module.exports = {
verbose: true,
testPathIgnorePatterns: [
"/node_modules/",
".tmp",
".cache"
],
modulePaths: [
"/node_modules/",
],
testEnvironment: "node",
};
./config/env/test/database.json
{
"connection": {
"client": "sqlite",
"connection": {
"filename": ".tmp/test.db"
},
"useNullAsDefault": true,
"pool": {
"min": 0,
"max": 1
}
}
}
./tests/helpers/strapi.js
const Strapi = require("#strapi/strapi");
const fs = require("fs");
let instance;
async function setupStrapi() {
if (!instance) {
await Strapi().load();
instance = strapi;
await instance.server.mount();
}
return instance;
}
async function cleanupStrapi() {
const dbSettings = strapi.config.get("database.connection");
const tmpDbFile = dbSettings.connection.filename
//close server to release the db-file
await strapi.server.httpServer.close();
//delete test database after all tests
if (dbSettings && tmpDbFile) {
if (fs.existsSync(tmpDbFile)) {
fs.unlinkSync(tmpDbFile);
}
}
// close the connection to the database
await strapi.db.connection.destroy();
}
module.exports = { setupStrapi, cleanupStrapi };
Note that you need to have the /hello endpoint in your project as specified in the strapi docs for the next tests to pass.
./tests/app.test.js
const { setupStrapi, cleanupStrapi } = require("./helpers/strapi");
jest.setTimeout(15000);
beforeAll(async () => {
await setupStrapi();
});
afterAll(async () => {
await cleanupStrapi();
});
it("strapi is defined", () => {
expect(strapi).toBeDefined();
});
require('./hello')
./tests/hello/index.js
const request = require('supertest');
it('should return hello world', async () => {
await request(strapi.server.httpServer)
.get('/api/hello')
.expect(200) // Expect response http code 200
});
I hope this helps anyone struggling with the same issues. I will update the answer as I progress.
I have a Webhook that POSTs a JSON to my Cloud Function Trigger URL.
I want the Cloud Function to parse the JSON and write it to my Cloud Firestore.
I've tested the Webhook on webhook.site & requestbin.com : they are both receiving the POST request perfectly.
I am guessing that there is some syntax problem somewhere here, around the payload or req.body.
exports.wooCommerceWebhook = async (req, res) => {
const payload = req.body;
Additionally, this is not an authenticated request, and I deployed the function through the Google Cloud Platform - Cloud Function Console. I did not deploy this through the CLI, or through an application setup with firebase.
index.js
const admin = require('firebase-admin')
admin.initializeApp();
exports.wooCommerceWebhook = async (req, res) => {
const payload = req.body;
// Write to Firestore - People Collection
await admin.firestore().collection("people").doc().set({
people_Email: payload.billing.email,
people_FirstName: payload.billing.first_name,
people_LastName: payload.billing.last_name,
});
return res.status(200).end();
};
package.json
{
"name": "sample-http",
"version": "0.0.1",
"dependencies": {
"firebase-admin": "^9.4.2"
}
}
My Webhook that delivers a POST JSON to my Cloud Function URL:
{
"billing": {
"email": "test#test.com",
"first_name": "First",
"last_name": "Last"
}
}
EDIT:
I've added
.catch((err) => { console.log(err); })
and now my logs are returning:
Unhandled rejection
TypeError: Cannot read property 'email' of undefined at exports.wooCommerceWebhook (/workspace/index.js:18:43)
at /layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:98:17
at processTicksAndRejections (internal/process/task_queues.js:77:11)
Function execution took 599 ms, finished with status: 'crash'
Error detected in test-function-1
I needed to declare each field's data type first.
let billing = "";
let people_Email = "";
let people_FirstName = "";
let people_LastName = "";
i am trying to update fields using this
exports.updateRawmaterial = (req, res) => {
// console.log(req.rawmaterial._id)
Rawmaterial.findByIdAndUpdate({ _id: req.rawmaterial._id }, { $set: req.body }, { new: true, useFindAndModify: false },
(err, updatedRawmaterial) => {
if (err) {
return res.status(400).json({
error: "NOT able to update rawmaterial"
});
}
return res.json(updatedRawmaterial);
})
}
please help me
#laxman
please check that you are using
app.use(bodyParser.json());
As a Middleware. include this middleware to convert and recognize the incoming Request Object as a JSON Object.
next thing please check you must do
req.body.rawmaterial._id if you are doing a post request from somewhere.
check if while doing the request the data is being sent or not.
This 3 steps will surely resolve this issue.
Thanks,
Dhruv Barot
If still not resolved then pls comment.
the problem was in routes i was not calling my routes correctly there was some spelling mistake in my route
router.put("/rawmaterial/:rawmaterialId/:userId", updateRawmaterial);
i had spell mistake in :rawmaterialId
As I am deploying my Nuxt JS universal app on Zeit Now, I was trying to take advantage of Zeit's Cache-Control header which is mentioned in Zeit Cache Doc.
Then I tried to look for how can I add the Cache-Control header in my Nuxt JS app and fortunately found this GitHub issue which was explaining the same thing.
Now as I was using serverMiddleware anyways in my Nuxt app to get the currently logged-in user's data using firebase-admin, so I thought I would easily add the response header in my code and so I did. In my /serverMiddleware/handleCookie.js I have it like this:
const Cookies = require('cookies')
const admin = require('../services/firebase-admin-init')
export default async (req, res, next) => {
res.setHeader('Cache-Control', 's-maxage=1000, stale-while-revalidate')
try {
const authUser = await verifyCookie(req, res)
if (authUser) {
const userData = await fetchUserDetailsFromFirestore(
req,
authUser.uid,
authUser.email_verified
)
if (userData) {
next()
}
} else {
next()
}
} catch (error) {
console.error(error)
}
}
Now the crazy thing is when I run dev i.e. yarn nuxt and check my site over localhost, I can easily see my added header in Chrome Network Tool.
But when I push my project to Zeit Now for hosting using now --prod and check my actual site, I do not see this header.
Now I am not understanding if I am doing something wrong, cause if I did, it should not have shown up in the localhost dev response header. I spend many days trying to fix this but went nowhere. Go no clue why this is happening. I am also using nuxt/now-builder for the Zeit deployment and here is my now.json file.
{
"version": 2,
"regions": ["bom1"],
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder",
"config": {
"serverFiles": [
"services/firebase-admin-init.js",
"serverMiddleware/**"
]
}
}
]
}
If anyone can help in this matter, it would be really helpful.
Your bug is related to time and async. In dev, everything works fast, but in prod, you need to wait longer for the promises to be resolved, the server is a little slow. Should be happening something like if authUser but not userdata, in this case you not has next() function.
I refactoring your middleware, the following code structure should help.
export default (req, res, next) => {
res.setHeader('Cache-Control', 's-maxage=1000, stale-while-revalidate')
verifyCookie(req, res)
.then((authUser) => {
if (authUser) {
fetchUserDetailsFromFirestore(
req,
authUser.uid,
authUser.email_verified
)
.then(() => {
next()
})
.catch((error) => {
console.error(error)
})
} else {
next()
}
})
.catch((error) => {
console.error(error)
})
}
I have a azure function,
In index.js i have the following code
module.exports = function (context, req) {
const createHandler = require('azure-function-express').createHandler;
const app = require('express')();
app.get("/home", (req, res) => {
const y = { "name": "name", "dob": "ddmmyyyy" }
context.res = y
context.done()
});
module.exports = createHandler(app);
context.done();
};
i have function.json :
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "{*segments}"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
],
"disabled": false
}
i have the above files in my azure function but i am not able get any output i just a blank page if i hit the api end point.
i have to use express to handle many other end points is there any way to handle in azure functions.
when i use nodejs local application setup, i am able to use express and handle many api end points with in a single module is that possible in azure functions? or i have to use different functions for each end point
See code below. We can use Azure function as a common express app.
const createHandler = require('azure-function-express').createHandler;
const app = require('express')();
app.get("/home", (req, res) => {
res.json({ "name": "name", "dob": "ddmmyyyy" });
});
app.get("/work", (req, res) => {
res.json({ "name": req.query.name, "dob": "ddmmyyyy" });
});
module.exports = createHandler(app);
module.exports = function (context, req) and context.done() are no longer useful if azure-function-express is in use. If you want to use other method of context, use req.context instead. See azure-function-express module doc.
Besides, Azure function has a prefix "api" in route by default, if you don't need it(like code above), change it to empty your host.json.
If your function runtime is ~2(beta).
{
"version": "2.0",
"extensions": {
"http": {
"routePrefix": ""
}
}
}
Else in ~1
{
"http": {
"routePrefix": ""
}
}
I have also use try this azure-function-express package but its still in the development and need a-lot of improvement. The best package i found is Azure AWS Severless Express
Package. Its very easy to use and compatible. You can easily use the Express with azure functions