Skip to content

Instantly share code, notes, and snippets.

@gregfenton
Last active May 16, 2023 17:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregfenton/c858085837edea71ec8fba6d5eabf175 to your computer and use it in GitHub Desktop.
Save gregfenton/c858085837edea71ec8fba6d5eabf175 to your computer and use it in GitHub Desktop.
Downloads all docs in a Firestore collection and stores as a JSON file -- command-line JavaScript/node
/**
* get_firestore_collection_as_json.js
*
* This code is a "node script" used to fetch all documents from a Firestore collection,
* either in "the cloud" or the emulator, and write them to a file as JSON.
*
* The script is a "client app", so it logs in with Firebase Auth using email/password from the variable USER1.
* This USER1 user (the.admin.guy@test.com) must exist in your Firebase project and have read access
* to the collection(s) you are populating. You can create that account via
* Firebase Console >> Authentication.
*
* This script is assumed to live in an existing Javascript project that has its own package.json.
* I store this script in <PROJECT_ROOT>/tools/fs-to-json/.
*
* To use:
* 1. Import the 'firebase' and 'esm' NPM modules to your project (Run the command: `npm install firebase esm`)
* 2. Edit the data for USER1 and FIREBASE_CONFIG, then adjust parameters in `main` for the call to `visitDocs`.
*
* NOTE: this code works with the Firebase Web SDK v9 API. Earlier revisions used the v8 API.
*
* Steps to use this repo:
* 1. Create a new directory and copy the 2 files (package.json & get_firestore_collection_as_json.js) to it
* 2. Run the command: npm install
* 3. Run the command: npm run tool:fetch-data
*
* (Note: the command `tool:fetch-data` is defined in package.json)
*/
import * as fs from 'fs';
import {initializeApp} from 'firebase/app';
import {
addDoc,
collection,
connectFirestoreEmulator,
getDocs,
getFirestore,
writeBatch
} from 'firebase/firestore';
import {getAuth, signInWithEmailAndPassword} from 'firebase/auth';
let FIRESTORE;
let AUTH;
// Firebase Console >> Authentication
const USER1 = {
email: 'mr.magoo@test.com', // USER THAT EXISTS IN FIREBASE AUTH
password: 'let_me_in',
uid: UID_FROM_FIREBASE_AUTH_FOR_THIS_USER
};
const initializeFB = async () => {
// USE YOUR FIREBASE PROJECT SETTINGS:
// Firebase Console >> Project Overview >> Apps
// >> (select or "Add App" web app) >> Config
const firebaseConfig = {
apiKey: VALUES_FROM_FIREBASE_APP_CONFIG,
appId: VALUES_FROM_FIREBASE_APP_CONFIG,
authDomain: VALUES_FROM_FIREBASE_APP_CONFIG,
databaseURL: VALUES_FROM_FIREBASE_APP_CONFIG,
messagingSenderId: VALUES_FROM_FIREBASE_APP_CONFIG,
projectId: VALUES_FROM_FIREBASE_APP_CONFIG
};
let fbApp = initializeApp(firebaseConfig);
FIRESTORE = getFirestore(fbApp);
let USING_FIREBASE_EMULATOR = true;
if (USING_FIREBASE_EMULATOR) {
// I explicitly set "host" and "port" in firebase.json so that devices
// on my local network can access the emulator:
// "emulators": {
// "functions": {
// "port": 5001,
// "host": "192.168.1.53"
// },
// "firestore": {
// "port": 5002,
// "host": "192.168.1.53"
// },
// ...
//
connectFirestoreEmulator(FIRESTORE, '192.168.1.53', 5002);
}
try {
AUTH = getAuth();
await signInWithEmailAndPassword(AUTH, USER1.email, USER1.password);
let currUser = AUTH.currentUser;
console.log(`Logged in with USER1 uid(${currUser.uid})`);
} catch (ex) {
console.error(ex.message);
throw ex;
}
};
const die = (msg) => {
console.error(msg);
process.exit(1);
};
const getDocuments = async (collectionName) => {
let retVal = [];
try {
let collectionRef = collection(FIRESTORE, collectionName);
let querySnap = await getDocs(collectionRef);
for (let i = 0; i < querySnap.size; i++) {
retVal.push({
_DOCUMENT_ID_: querySnap.docs[i].id,
...querySnap.docs[i].data()
});
}
} catch (ex) {
die(`ERROR getDocuments():: ${ex.message}`);
}
return retVal;
};
const main = async () => {
console.log('>>> START LOADING Users - ', Date());
await initializeFB();
let collectionName = 'user';
let allDocs = await getDocuments(collectionName);
let jsonFile = `./${collectionName}.json`;
fs.writeFileSync(jsonFile, JSON.stringify(allDocs, null, 2), (err) => {
if (err) {
die(`EXCEPTION while writing JSON file: ${err.message}`);
}
console.log(`JSON data saved to (${jsonFile})`);
});
console.log('>>> DONE - output written to:', jsonFile);
process.exit();
};
main().catch((ex) => {
die('main() caught an exception: ' + ex.message);
});
{
"name": "gist",
"version": "0.0.1",
"description": "",
"main": "get_firestore_collection_as_json.js",
"scripts": {
"tool:fetch-data": "node -r esm ./get_firestore_collection_as_json.js 2>&1 | tee get_json.log"
},
"author": "https://github.com/gregfenton",
"license": "free",
"dependencies": {
"esm": "^3.2.25",
"firebase": "^9.6.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment