Last active
September 8, 2024 17:42
-
-
Save gregfenton/aad320f16b495aa3bbca86ad97e8ae53 to your computer and use it in GitHub Desktop.
Loads JSON data into a Firestore database (cloud or local emulator) -- command-line JavaScript/node
This file contains hidden or 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
/** | |
* load_json_to_firstore.js | |
* | |
* This code is a "node script" used to load data into your Firestore database, either in "the cloud" or the emulator. | |
* | |
* The script is a "client app", so it logs in with Firebase Auth using email/password from the variable USER1. | |
* | |
* The USER1 user ([email protected]) must exist in your Firebase project and have write access | |
* to the collection(s) you are populating. You can create that account via Firebase Console >> Authentication. | |
* | |
* 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 | |
* | |
* To run, I added to the package.json of my project: | |
* | |
* "scripts": { | |
* "load-data": "node -r esm ./load_json_to_firestore.js 2>&1 | tee load_json.log", | |
* | |
* | |
* and then run using the command: `npm run load-data`. | |
* | |
* Alternatively, you could just run the script directly with: | |
* `node -r esm ./load_json_to_firestore.js` | |
*/ | |
import { initializeApp } from 'firebase/app'; | |
import { | |
addDoc, | |
collection, | |
getFirestore, | |
connectFirestoreEmulator, | |
} from 'firebase/firestore'; | |
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'; | |
const USER1 = { | |
email: '[email protected]', | |
password: 'xxx', | |
}; | |
let FIRESTORE; | |
let AUTH; | |
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 loadUsers = async (collectionName, dataFile) => { | |
const data = require(dataFile); | |
const dataKey = 'users'; | |
let count = 0; | |
if ( | |
data && | |
typeof data === 'object' && | |
data[dataKey] && | |
typeof data[dataKey] === 'object' | |
) { | |
console.log( | |
`${dataFile} - have ${data[dataKey].length} records to process` | |
); | |
for (let i = 0; i < data[dataKey].length; i++) { | |
try { | |
let userRecord = data[dataKey][i]; | |
let collRef = collection(FIRESTORE, collectionName); | |
let docRef = await addDoc(collRef, userRecord); | |
console.log(`NEW DOC: ${collectionName}/${docRef.id}`); | |
} catch (ex) { | |
console.error(`Exception on`); | |
} | |
} | |
} else { | |
console.error(`ERROR: dataFile (${dataFile})`); | |
console.error(`ERROR: typeof data (${typeof data})`); | |
console.error(`ERROR: typeof data[${dataKey}] - (${typeof data[dataKey]})`); | |
} | |
}; | |
const main = async () => { | |
try { | |
console.log(`${Date()} >>> Initialize Firebase`); | |
await initializeFB(); | |
console.log(`${Date()} >>> Start Loading Users`); | |
await loadUsers('users', './data/users.json'); // loads users.json into "users" collection | |
console.log(`${Date()} >>> Success!`); | |
process.exit(0); | |
} catch(ex) { | |
console.log(`${Date()} >>> EXCEPTION: ${ex.message}`); | |
process.exit(1); | |
} | |
}; | |
main(); |
This file contains hidden or 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
{ | |
"users": [ | |
{ | |
"firstName": "Fred", | |
"lastName": "Flintstone", | |
"displayName": "Freddy My Boy", | |
"email": "[email protected]", | |
"role": "Staff", | |
}, | |
{ | |
"firstName": "Barney", | |
"lastName": "Rubble", | |
"displayName": "You Nitwit", | |
"email": "[email protected]", | |
"role": "Admin", | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment