Forked from gregfenton/firestore_add_field_to_all_docs_in_collection.js
Created
April 24, 2022 19:54
-
-
Save santiagoaloi/59e85abafaaab6237b8afce7b55c601a to your computer and use it in GitHub Desktop.
FIRESTORE: a node/JavaScript command-line script that visits all docs in a Firestore collection and updates them with the given values (in this example, we set/add an "enabled" field to TRUE) -- uses the Firebase Web SDK v9 API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* firestore_add_field_to_all_docs_in_collection.js | |
* | |
* 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/cleanup/. | |
* | |
* 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. | |
* | |
* To run: node firestore_add_field_to_all_docs_in_collection.js | |
* | |
* Alternatively, you can create a "script" in package.json: | |
* "scripts": { | |
* ... | |
* "add_field_to_fs": "node tools/cleanup/firestore_add_field_to_all_docs_in_collection.js" | |
* } | |
* | |
* and then run the script with: npm run firestore_add_field_to_all_docs_in_collection.js | |
*/ | |
import {initializeApp} from 'firebase/app'; | |
import { | |
addDoc, | |
collection, | |
connectFirestoreEmulator, | |
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 | |
}; | |
// Firebase Console >> Project Overview >> General >> Apps | |
// (use existing app values or click Add app to create new WEB app) | |
const FIREBASE_CONFIG = { | |
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 | |
}; | |
const initializeFB = async () => { | |
// USE YOUR FIREBASE PROJECT SETTINGS: | |
// Firebase Console >> Project Overview >> Apps | |
// >> (select or "Add App" web app) >> Config | |
const firebaseConfig = { | |
apiKey: 'xxx', | |
appId: 'xxx', | |
authDomain: 'xxx', | |
databaseURL: 'xxx', // use project value for cloud, or use emulator values such as "http://192.168.1.53:5001/" (see USE_FIREBASE_EMULATOR below) | |
messagingSenderId: 'xxx', | |
projectId: 'xxx' | |
}; | |
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 visitDocs = async ( | |
collectionPath, | |
field = null, | |
compareOp = null, | |
compareValue = null, | |
updateValue | |
) => { | |
let collRef = collection(FIRESTORE, collectionPath); | |
if (field && compareOp) { | |
collRef = query(collRef, where(field, compareOp, compareValue)); | |
} | |
let querySnap = getDocs(collRef); | |
console.log(`WHERE returned ${querySnap.size} records`); | |
let batch = writeBatch(FIRESTORE); | |
querySnap.forEach((docSnap) => { | |
console.log( | |
`UPDATING ${docSnap.ref.id} with: ${JSON.stringify(updateValue)}` | |
); | |
batch.update(docSnap.ref, updateValue); | |
}); | |
try { | |
await batch.commit(); | |
console.log('Transaction successfully committed!'); | |
} catch (ex) { | |
console.log(`Transaction failed: ${ex}`); | |
throw ex; | |
} | |
}; | |
const main = async () => { | |
console.log('>>> START LOADING Users - ', Date()); | |
await initializeFB(); | |
// add/set an "enabled" field to true for all docs in the 'users' collection | |
await visitDocs('users', null, null, null, {enabled: true}); | |
console.log('>>> DONE - ', Date()); | |
process.exit(); | |
}; | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment