This Firebase Cloud Function provides a remote procedure call (RPC) endpoint, allowing clients to execute functions defined elsewhere and receive results as JSON responses. It handles CORS requests, extracts function names from incoming data, and utilizes a custom getResult
function to execute the requested logic.
npm run import -- "firebase rpc wrapper"
var cors = require('cors')({origin: true});
var process = require('process');
var functions = require('firebase-functions');
var admin = require('firebase-admin');
var importer = require('../Core');
var getResult = importer.import("rpc result");
try {
admin.initializeApp(functions.config().firebase);
} catch (e) {
console.log(e);
}
if(typeof module.exports === 'undefined') {
module.exports = {};
}
module.exports.rpc = functions.https.onRequest((req, res) => {
process.env.HOME = process.env.HOMEPATH = process.env.USERPROFILE = '';
const config = functions.config();
const services = Object.keys(config).reduce(k => {
Object.keys(config[k]).forEach(s => {
process.env[k.toUpperCase() + '_' + s.toUpperCase()] = config[k][s];
});
});
cors(req, res, () => {
return Promise.resolve([])
.then(() => getResult({
command: req.body['function'] || req.query['function'],
result: importer.interpret(req.body['function'] || req.query['function']),
body: req.method === 'POST' ? req.body : req.query,
circles: ['Public']
}))
.then(r => {
const result = Object.getOwnPropertyNames(r).reduce((alt, key) => {
alt[key] = r[key] + '';
return alt;
}, {});
console.error(result);
return res.status(200).send(r);
})
// TODO: object assign error?
.catch(e => {
const result = Object.getOwnPropertyNames(e).reduce((alt, key) => {
alt[key] = e[key] + '';
return alt;
}, {});
console.error(result);
return res.status(500).send(result);
});
});
})
const admin = require('firebase-admin');
const firebaseFunctions = require('firebase-functions');
const importCore = require('../Core');
const rpcResult = importCore.import('rpc result');
admin.initializeApp(firebaseFunctions.config().firebase);
const cors = () => {
return (req, res, next) => {
next();
};
};
class Config {
constructor(config) {
this.config = config;
}
getServices() {
return Object.keys(this.config).reduce((acc, key) => {
Object.keys(this.config[key]).forEach((service) => {
const envKey = `${key.toUpperCase()}_${service.toUpperCase()}`;
process.env[envKey] = this.config[key][service];
});
return acc;
}, {});
}
}
class Rpc {
constructor(config) {
this.config = config;
this.services = new Config(config).getServices();
}
handleRequest(req, res) {
try {
const { body } = req;
const { command, result, body: data, circles } = this.interpretInput(body);
return rpcResult({
command,
result,
data,
circles,
})
.then((result) => {
return res.status(200).send(result);
})
.catch((error) => {
return res.status(500).send(error);
});
} catch (error) {
console.error(error);
return res.status(500).send(error);
}
}
interpretInput(input) {
const command = input['function'] || input.query['function'];
const result = importCore.interpret(input['function'] || input.query['function']);
const data = input.method === 'POST'? input.body : input.query;
const circles = ['Public'];
return { command, result, body: data, circles };
}
}
module.exports = (functions) => {
const rpc = new Rpc(functions.config());
return functions.https.onRequest(rpc.handleRequest);
};
This code sets up a Firebase Cloud Function that acts as a remote procedure call (RPC) endpoint.
Here's a breakdown:
Dependencies:
cors
for handling cross-origin requests, process
for environment variables, firebase-functions
for the Cloud Function framework, firebase-admin
for interacting with Firebase, and custom modules importer
and getResult
.Firebase Initialization:
Environment Setup:
RPC Endpoint:
rpc
that handles incoming requests.CORS Handling:
Request Processing:
getResult
function to interpret the function name and execute the corresponding logic.Error Handling: