Add middleware to all firebase functions in one line / function - javascript

In express you can add middleware such as app.use(cors()) which adds it to all of the endpoints, however I can't find something similar in firebase examples. Here is the example (see below) of how to apply it in every function. However I want to apply the middleware (cors or other) globally, as I have many functions.
import * as cors from 'cors';
const corsHandler = cors({origin: true});
export const exampleFunction= functions.https.onRequest(async (request, response) => {
corsHandler(request, response, () => { return handler(req, res) });
});
What is the equivalent of app.use() in firebase? Is adding and express server the only option?

Use currying to create a handler, you have to repeat it across all the functions, but it's easier than writing the middleware each time:
const applyMiddleware = handler => (req, res) => {
return cors(req, res, () => {
return handler(req, res)
})
}
exports.handler = functions.https.onRequest(applyMiddleware(yourHandler))
Edit, an example of a more complex middleware:
const applyMiddleware =
(handler, { authenticatedRoute = false } = {}) =>
(req, res) => {
if (authenticatedRoute) {
const isAuthorized = isAuthenticated(req)
if (!isAuthorized) {
return res.status(401).send('Unauthorized')
}
}
return cors(req, res, () => {
return handler(req, res)
})
}
exports.handler = functions.https.onRequest(
applyMiddleware(yourHandler, { authenticatedRoute: true })
)

import cors from 'cors'
const corsHandler = cors({origin: true});
const applyCORS = handler => (req, res) => {
return corsHandler(req, res, _ => {
return handler(req, res)
})
}
export const firebasefunc = functions.https.onRequest(applyCORS(myhandler))

Related

to be under different domain, why axios.post dont work

https://github.com/skyturkish/e_commerce_advance this is the repo
index.js
const express = require('express')
const bodyParser = require('body-parser')
const UserService = require('./services/user-service')
const app = express()
app.set('view engine', 'pug')
app.use(bodyParser.json())
app.get('/', (req, res) => {
res.render('index')
})
app.get('/users/all', async (req, res) => {
const users = await UserService.findAll()
res.render('user', { users })
})
app.get('/users/:id', async (req, res) => {
const user = await UserService.find(req.params.id)
res.send(user)
})
app.post('/users', async (req, res) => {
const user = await UserService.add(req.body)
res.send(user)
})
app.delete('/users/:id', async (req, res) => {
const user = await UserService.del(req.params.id)
res.send(user)
})
app.listen(3000, () => {
console.log('Server listening')
})
When I try to add a new user under "http://localhost:3000/" or "http://localhost:3000/users/all", this works. But under http://localhost:3000/users/1 throw an error. I cant understand well, why this happens, how does being under a domain authorize and receive it.
The GET handlers for / and /users/all use res.render(), but the GET handler for /users/:id uses res.send() (so it doesn't render your template, which in turn loads the axios library).

Node JS CORS module not setting Access-Control-Allow-orgin express header

I am trying to create api and fetch it from front but the "Access-Control-Allow-Origin" is not allowing me.
I tried to solve the problem
but still showing me the problem.
this is the front part
I fetched it by GET method but not working
const api = "http://localhost:3000/api/posts/";
const base_api = "http://localhost:3000/";
console.log(api);
window.onload = () => {
getPost();
};
const getPost = () => {
fetch( api , {
method: "GET",
})
.then((response) => {
return response.json();
})
.then((data) => {
buildPost(data);
console.log(data);
});
};
const buildPost = (blogPost) => {
console.log(blogPost);
*this is the express part
I used the "*" that still showing the error. what more solution could be
const express = require("express");
const app = express();
const Post= require("./api/models/posts");
const postsData= new Post();
app.use((req, res, next) =>{
res.setHeader("Access-Control-Allow-Orgin","*" )
next();
})
app.use(express.json());
app.use ('/uploads', express.static('uploads'))
app.get("/api/posts", (req, res)=>{
res.status(200).send(postsData.get())
});
app.get("/api/posts/:post_id", (req, res)=>{
const postId = req.params.post_id;
const foundedPost= postsData.getEachData(postId);
});
app.listen(3000, ()=> console.log("Listening on
http://localhost:3000/"))

How to use middleware with router.verb() in koa

I'm using Koa.js and I was wondering how I could use a middleware with router.verb()
As mentioned here router.use([path], middleware) I tried like below.
The console.log() trigger but the users.list is not called
My main objective is to do an auth middleware
const Router = require("#koa/router");
const router = new Router();
const users = require("./Controllers/users/index.js");
router.use("/user", (ctx, next) => {
console.log(ctx);
next();
});
router.get("/user", users.list)
I don't get any error messages but the users.list don't execute.
Then i tried this
router.get("/user", (ctx, next) => {
console.log(ctx);
next();
}, users.list)
But i don't get any change and I feel like I don't understand something, but can't figure out what
In my index.js
const Koa = require("koa");
const router = require("./Routes");
const bodyParser = require("koa-bodyparser");
const cors = require("#koa/cors");
const serve = require("koa-static");
const path = require("path");
const errorHandler = require("./Middlewares/errorHandler");
const app = new Koa();
app.use(errorHandler)
.use(bodyParser())
.use(cors())
.use(router.routes())
.use(serve(path.join("public", "ads")))
.use(router.allowedMethods());
in my controller
const { Users } = require("../../Models");
module.exports = {
list: async (ctx, next) => {
let AllUsers = await Users.findAll();
ctx.body = AllUsers;
}
}
I got it working with adding await next()
router.use("/ads", async (ctx, next) => {
console.log(ctx);
await next();
});
Since my controller is an async function I get my explanations from here -> async/await always returns promise

How to create function with parameter can pass express.get() method?

app variable is defined by
const app = express();
This code is working fine:
app.get('/posts/:id', (req, res) => {
res.json( post_creator.CreatePost(req.params.id) );
});
But the below code is not working:
const post_url_with_id = '/posts/:id';
app.get(post_url_with_id, (req, res) => {
res.json( post_creator.CreatePost(req.params.id) );
});
How can i create function with parameter can pass express.get or post methods?
I want to implement like next function
function serve_post( post_url_with_id ) {
app.get(post_url_with_id, (req, res) => {
res.json( post_creator.CreatePost(req.params.id) );
});
}
Thanks for contributors.
This can be implemented by passing express app like:
// someRoute.js
function serve_post(app, post_url_with_id ) {
app.get(post_url_with_id, (req, res) => {
res.json( post_creator.CreatePost(req.params.id) );
});
}
module.exports = serve_post;
In your file where you've instantiated express (where you have app)
const app = express();
// assuming they are in same folder
const someRoute = require('./someRoute');
someRoute(app, post_url_with_id);

Express.js: Pass asynchronous errors thrown

I notice a recurring pattern in my express app which I think could be optimized. Basically I have a route calling a method with some asynchronous functions.
index.js
const controller = require('./controller.js');
const router = new Router();
router.post('/user', controller.createUser);
module.exports = router;
controller.js
exports.createUser = async (req, res, next) => {
try {
// asynchronous calls, etc.
} catch (e) {
// pass error to middleware
next(e);
}
}
The try/catch blocks are recurring in each of my controller methods. I'd want errors caught to be passed to my error-handling middleware. Therefore it seems impractical and repetitive to pass errors in each of my controller functions. Could I refactor this?
What if I wrap the controller method in a function as such:
index.js
const controller = require('./controller.js');
const router = new Router();
const handleErrors = (func) => async (req, res, next) => {
try { await func(req, res, next) }
catch (e) { return next(e) }
};
router.post('/user', handleErrors(controller.createUser));
module.exports = router;
controller.js
exports.createUser = async (req, res, next) => {
// asynchronous calls, etc.
if (a !== b) {
// errors can be passed to middleware as such
throw new CustomError(400, 'a is not equal to b');
}
}
Would this be an appropriate solution? Does Express have any built-in ways of accomplishing the same thing? Should I be cautious about refactoring my entire application in this way?
Would this be an appropriate solution?
Yes, looks nice.
Does Express have any built-in ways of accomplishing the same thing?
No, Express was written before async / await was introduced.
Should I be cautious about refactoring my entire application in this way?
I don't think so. How i would write that:
const handleErrors = (func) => (req, res, next) => func(req, res).then(() => next(), next);
I recommend you this article: https://medium.com/#Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
As in the article, this should be the middleware:
const asyncMiddleware = fn =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
};
This is how a controller should look like:
router.get('/users/:id', asyncMiddleware(async (req, res, next) => {
/*
if there is an error thrown in getUserFromDb, asyncMiddleware
will pass it to next() and express will handle the error;
*/
const user = await getUserFromDb({ id: req.params.id })
res.json(user);
}));
router.post('/users', asyncMiddleware(async (req, res, next) => {
const user = await makeNewUser(req.body);
res.json(user)
}))

Categories