Skip to content

Instantly share code, notes, and snippets.

@ShaMan123
Last active July 24, 2021 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShaMan123/89c103ac89749d6e8ae1db29865e0c95 to your computer and use it in GitHub Desktop.
Save ShaMan123/89c103ac89749d6e8ae1db29865e0c95 to your computer and use it in GitHub Desktop.
react firebase dev proxy
/**
* Add this file in your app at `src/setupProxy.js`
* It will proxy outbound requests from your app (while in dev mode) to your firebase functions emulator.
*
* Make sure you've changed the consts!
* After that simply start the react dev server and the firebase functions emulator.
*
* Patches the behavior of `firebase.functions().useEmulator` for `onRequest` http functions.
* https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually
*
* https://github.com/chimurai/http-proxy-middleware#http-proxy-middleware-options
*/
const fs = require('fs');
const { createProxyMiddleware } = require('http-proxy-middleware');
const _ = require("lodash");
const path = require("path");
//-------------------------------------------------- CHANGE ME ----------------------------------------------------------
/**
* Path to firebase root folder, where all config files reside
* Assuming the app is a direct child of the firebase folder and that this file resides under `src`
* `../firebase_root/${APP}/src/setupProxy.js`
*/
const FIREBASE_ROOT = path.resolve(__dirname, '..', '..');
/**
* Hosting target name as defined in your firebase project (.firebaserc)
*/
const APP = 'web-app';
//------------------------------------------------------------------------------------------------------------------------------
function getBaseUrl() {
const config = require(path.resolve(FIREBASE_ROOT, 'firebase.json'));
return `http://localhost:${config.emulators.functions.port}`
}
function getProjectName() {
const firebaseConfig = JSON.parse(fs.readFileSync(path.resolve(FIREBASE_ROOT, '.firebaserc')).toString());
return firebaseConfig.projects.default;
}
function getAppRewrites() {
const config = require(path.resolve(FIREBASE_ROOT, 'firebase.json'));
const appConfig = _.find(config.hosting, data => data.target === APP);
return appConfig.rewrites;
}
function findFirebaseRewrite(reqPath) {
return _.find(getAppRewrites(), data => {
const regex = data.source.replace(/\*\*/g, '.*');
return new RegExp(regex).test(reqPath);
});
}
function getTrigger(functionName) {
const triggers = require(path.resolve(FIREBASE_ROOT, 'functions'));
let found = null;
const traverseFirebaseFunctions = (value, key) => {
if (typeof value === 'function' && key === functionName) {
found = {
...value.__trigger,
key
};
} else if (!found && typeof value === 'object') {
_.forEach(value, (sub, subKey) => traverseFirebaseFunctions(sub, `${key}-${subKey}`));
}
};
_.forEach(triggers, (trigger, key) => traverseFirebaseFunctions(trigger, key));
return found;
}
module.exports = app => {
_.forEach(getAppRewrites(), rewrite => {
if (rewrite.function) {
const trigger = getTrigger(rewrite.function);
app.use(rewrite.source, createProxyMiddleware(rewrite.source, {
target: `${getBaseUrl()}/${getProjectName()}/${trigger.regions ? trigger.regions[0] : 'us-central1'}/${trigger.key}`,
pathRewrite: (path, req) => { return path.replace(rewrite.source.replace('/**', ''), '') }
}));
} else if (rewrite.destination) {
/*
app.use(rewrite.source, createProxyMiddleware(rewrite.source, {
target: '',
pathRewrite: {
[rewrite.source]: rewrite.destination
}
}));
*/
}
})
};
@ShaMan123
Copy link
Author

ShaMan123 commented Jul 18, 2021

This file proxies outbound requests from your react app (while in dev mode) to your firebase functions emulator.
It patches the behavior of firebase.functions().useEmulator for onRequest http functions.
https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually

You need to add dev deps:

yarn add --dev lodash http-proxy-middleware`

With a bit more work destination rewrites can be supported as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment