Skip to content

Instantly share code, notes, and snippets.

@mbleigh
Last active January 16, 2025 04:52
Show Gist options
  • Save mbleigh/9c8680cf319ace2f506f57380da66e7d to your computer and use it in GitHub Desktop.
Save mbleigh/9c8680cf319ace2f506f57380da66e7d to your computer and use it in GitHub Desktop.
Firebase Hosting Fetch All Files

Fetch All Files from Firebase Hosting

This script fetches all of the files from the currently deployed version of a Firebase Hosting site. You must be signed in via the Firebase CLI and have "Site Viewer" permission on the site in question to be able to properly run the script.

Running via NPX

npx https://gist.github.com/mbleigh/9c8680cf319ace2f506f57380da66e7d <site_name>

Where <site_name> is your Firebase Hosting site (e.g. my-site from my-site.firebaseapp.com). The files will be downloaded into a folder <site_name>_<version_id> where the version ID is the current version of your site.

#!/usr/bin/env node
const requireAuth = require('firebase-tools/lib/requireAuth');
const api = require('firebase-tools/lib/api');
const fs = require('fs-extra');
const request = require('request');
if (!process.argv[2]) {
console.error(`
ERROR: Must supply a site name. Usage:
node fetchFiles.js <site_name>`);
process.exit(1);
}
const site = process.argv[2];
async function getLatestVersionName() {
const result = await api.request('GET', `/v1beta1/sites/${site}/releases?pageSize=1`, {
auth: true,
origin: api.hostingApiOrigin,
});
const release = (result.body.releases || [])[0];
if (release) {
return release.version.name;
}
return null;
}
const LIST_PAGE_SIZE = 1000;
async function listFiles(versionName, existing = [], pageToken = null) {
const result = await api.request('GET', `/v1beta1/${versionName}/files?pageSize=${LIST_PAGE_SIZE}${pageToken ? `&pageToken=${pageToken}` : ''}`, {auth: true, origin: api.hostingApiOrigin});
result.body.files.forEach(file => existing.push(file.path));
if (result.body.nextPageToken) {
return await listFiles(versionName, existing, result.body.nextPageToken);
}
return existing;
}
const MAX_FETCHES = 100;
(async function() {
try {
await requireAuth({}, ['https://www.googleapis.com/auth/cloud-platform']);
const v = await getLatestVersionName();
const vid = v.split('/')[v.split('/').length - 1];
const toFetch = await listFiles(v);
const dirName = `${site}_${vid}`;
let fetchesOutstanding = 0;
let fetchCount = 0;
function fetch() {
if (fetchesOutstanding >= MAX_FETCHES) {
return;
} else if (toFetch.length === 0) {
console.log();
console.log("Complete. Fetched", fetchCount, "files.");
return;
}
const f = toFetch.shift();
console.log('Fetching', f);
fetchesOutstanding++;
fetchCount++;
fs.ensureFileSync(dirName + f);
const q = request(`https://${site}.firebaseapp.com${f}`)
const ws = fs.createWriteStream(dirName + f);
q.pipe(ws);
ws.on('finish', () => {
console.log('Fetched ', f);
fetchesOutstanding--;
fetch();
});
}
fetch();
} catch (e) {
console.error("ERROR:", e.stack);
process.exit(1);
}
})();
{
"name": "firebase-hosting-fetch-version",
"version": "0.1.0",
"bin": "./fetchFiles.js",
"dependencies": {
"firebase-tools": "^7.4.0",
"fs-extra": "^8.1.0",
"request": "^2.88.0"
}
}
@gaberilde
Copy link

I posted the above url fix myself for convinience
https://gist.github.com/gaberilde/4c2d55d8c6de0772ca49c8b473dff442

@Enrollmedicare
Copy link

We are so confused. We have Node.js and NPM downloaded. We are logged in to our Firebase through CLI. We requested Firebase to list projects we have access to. It gave us the Project ID. We have pasted the gist.github.com/mbleigh link above and at the end we have listed our Project ID (which does not include .firebase.app at the end). We have tried with a space between the link and the project name, without a space, with <> and without <>. We continue getting this response.
npm ERR! code ENOENT
npm ERR! syscall spawn git
npm ERR! path git
npm ERR! errno -4058
npm ERR! enoent An unknown git error occurred
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

Please help anyone?! Thank you!

@Brianceasar
Copy link

@mbleigh Worked for me thank you a alot. 👍

@halans
Copy link

halans commented Jun 29, 2024

Was getting
FirebaseError: HTTP Error: 401, Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.

Had to do:
firebase login --reauth

After which it worked fine.

@drewtadams
Copy link

for anyone that runs into a 404, i had to use the project id instead of the name and it worked

@sekhsoyebali
Copy link

I had the 404 issue. I used the project ID instead of the <site_name>, and it resolved the issue.

<project_id>.firebaseapp.com
npx https://gist.github.com/mbleigh/9c8680cf319ace2f506f57380da66e7d <project_id>

@askeijaz
Copy link

askeijaz commented Oct 5, 2024

I had the 404 issue. I used the project ID instead of the <site_name>, and it resolved the issue.

<project_id>.firebaseapp.com
npx https://gist.github.com/mbleigh/9c8680cf319ace2f506f57380da66e7d <project_id>

Yes, this is the only solution that worked for me. However, is the complete website being pulled down? How can one confirm?

@remy-burney-pf
Copy link

Is there a similar way to retrieve firebase functions ?

@remy-burney-pf
Copy link

Is there a similar way to retrieve firebase functions ?

It looks like for Firebase functions we can get the source code from Google cloud.

@slodziak
Copy link

Not sure if this is still helpful @Enrollmedicare but the error:
npm ERR! syscall spawn git
was caused by your machine missing git. You should make sure it is installed.

@Andrew-Chen-Wang
Copy link

I had the 404 issue. I used the project ID instead of the <site_name>, and it resolved the issue.

npx https://gist.github.com/mbleigh/9c8680cf319ace2f506f57380da66e7d <project_id>

+1 to this comment; use the project id via firebase projects:list or npx firebase projects:list

@SpaceshipxDev
Copy link

THANK YOU SO MUCH FOR YOUR WORK, MAY THE SIMULATION BLESS US ALL

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