Skip to content

Instantly share code, notes, and snippets.

@AlissonEnz
Created March 18, 2020 00:00
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AlissonEnz/e4350042a93b7732d3fe9fb138f81b11 to your computer and use it in GitHub Desktop.
Save AlissonEnz/e4350042a93b7732d3fe9fb138f81b11 to your computer and use it in GitHub Desktop.
Firebase Batch Deploy Functions
// Firebase Batch Functions Deploy (Alisson Enz)
// This script helps firebase users deploy their functions when they have more than 60 functions and
// it's not allowed to deploy all using `firebase deploy --only functions` due deployment quota.
// This script will get your functions export from index.js and deploy in batches of 30 and wait 30 seconds.
// This script will NOT delete your function when removed from index.js.
// Instructions
// 0. This instructions suppose that you already have firebase-tools installed and is logged to your account;
// 1. Install `shelljs` (npm install -g shelljs);
// 2. Change the path to point to your index.js at line 16;
// 3. run `yarn ./functionsDeploy` to deploy your functions;
const shell = require('shelljs');
const myFunctions = require('./index'); // Change here
if (!shell.which('firebase')) {
shell.echo('Sorry, this script requires firebase');
shell.exit(1);
}
const execShellCommand = cmd => {
return new Promise((resolve, reject) => {
shell.exec(cmd, (error, stdout, stderr) => {
if (error) console.warn(error);
resolve(stdout ? stdout : stderr);
});
});
};
const asyncForEach = async (array, callback) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
};
let count = 0;
let batchesCount = 0;
let batches = [];
const LIMIT = 30;
batches[batchesCount] = 'firebase deploy --only';
Object.keys(myFunctions).forEach(f => {
if (count === 0) {
batches[batchesCount] += ` functions:${f}`;
count += 1;
} else if (count < LIMIT) {
batches[batchesCount] += `,functions:${f}`;
count += 1;
} else {
count = 1;
batchesCount += 1;
batches[batchesCount] = `firebase deploy --only functions:${f}`;
}
});
console.log('\nTotal: ', Object.keys(myFunctions).length);
const save = async () => {
try {
await asyncForEach(batches, async b => {
console.log(b);
await execShellCommand(`${b} --force`);
await execShellCommand('sleep 30s');
});
} catch (e) {
console.warn(e);
} finally {
console.log('\nDone!\n');
}
};
return save();
@grrrian
Copy link

grrrian commented Apr 23, 2020

Thanks for this!

Do you get this warning when running it:
Warning, FIREBASE_CONFIG and GCLOUD_PROJECT environment variables are missing. Initializing firebase-admin will fail

I'm wondering if it explains why this works when I run it locally, but it fails when I run it on Bitbucket Pipelines because it cannot resolve FirebaseFunctions.config()

@AlissonEnz
Copy link
Author

Thanks for using @grrrian

It started to show this warning after updating to Node 10.
I didn't find a solution yet, but as soon as I discover how to solve it I'll update this gist.
If you find a solution, you are more than welcome to help 😃

@AlissonEnz
Copy link
Author

Hey @grrrian,

I discovered how to solve, IDK if you are still using it, but anyway haha.

  1. Create a .env file as following (doesn't matter the values itself, it just need to have something)
FIREBASE_CONFIG=anything
GCLOUD_PROJECT=anything
  1. Install env-cmd dependency (I installed on devDependencies)
  2. Then you can add to your package.json scripts the following:
    "deploy-functions": "env-cmd -f ./path-to-env/dev.env node ./path-to-functionsDeploy/index.js"
  3. Now it should work npm run deploy-functions 😃

@jasan-s
Copy link

jasan-s commented Feb 26, 2021

@AlissonEnz is the above solution still how you deploy in batch?

@nilsreichardt
Copy link

Is this still needed to deploy the functions in batches? Because I see in the command line, that Firebase CLI tries to redeploy the functions:

i  functions: updating Node.js 12 function onNotificationUpdate(europe-west1)...
⚠  functions: got "Quota Exceeded" error while trying to update projects/myProject/locations/europe-west1/functions/removeFriend. Waiting to retry...
⚠  functions: got "Quota Exceeded" error while trying to update projects/myProject/locations/europe-west1/functions/chat-onSendDmChatMessage. Waiting to retry...
⚠  functions: got "Quota Exceeded" error while trying to update projects/myProject/locations/europe-west1/functions/onNotificationUpdate. Waiting to retry...
⚠  functions: got "Quota Exceeded" error while trying to update projects/myProject/locations/europe-west1/functions/lookUpIp. Waiting to retry...
⚠  functions: got "Quota Exceeded" error while trying to update projects/myProject/locations/europe-west1/functions/writeMessageWithSupportAccount. Waiting to retry...
✔  functions[resetSawBoardInFeed(europe-west1)]: 

@AlissonEnz
Copy link
Author

Hi guys, I don't think it's still necessary to use it to deploy in batches. It's been a long time that I don't use it anymore

@nilsreichardt
Copy link

I found the PRs and the version, where they added it: Since version 9.9.0 the firebase-tools will retry the functions, which failed because of a Ouota Exceeded error.

Changelog of 9.9.0: https://github.com/firebase/firebase-tools/releases/tag/v9.9.0
PR: firebase/firebase-tools#3246

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