Skip to content

Instantly share code, notes, and snippets.

@dulimarta
Created February 25, 2025 21:07
Show Gist options
  • Save dulimarta/3c7e703084268e53aa8256e8e04c9dba to your computer and use it in GitHub Desktop.
Save dulimarta/3c7e703084268e53aa8256e8e04c9dba to your computer and use it in GitHub Desktop.
Cloud Firestore CRUD operations (Winter 2025)
export type State = {
// abbreviation: string
name: string;
capital: string;
population: number;
nationalParks: Array<string>;
};
export type City = {
name: string;
population_per_sqmile: number;
};
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
import { cs371_demo_config } from "./my_fb_config";
// Initialize Firebase
const app = initializeApp(cs371_demo_config);
console.info("My Firebase Web App", app);
import { initializeApp } from "firebase/app";
import { cs371_demo_config } from "./my_fb_config";
import { State } from "./00-types";
import {
addDoc,
collection,
doc,
getFirestore,
setDoc,
} from "firebase/firestore";
// Initialize Firebase (Do this only once through your web app)
const app = initializeApp(cs371_demo_config);
const db = getFirestore();
const mich: State = {
name: "Michigan",
population: 8_000_000,
capital: "Lansing",
nationalParks: ["Pictured Rocks National Lakeshore", "Hoffmaster State Park"],
};
const flor: State = {
name: "Florida",
population: 20_200_000,
capital: "Tallahassee",
nationalParks: ["Everglades National Park"],
};
// Option #1: Add a new document to a (new or existing) collection
// Side Effect: this always creates a new document every time you
// run this code
const stateColl = collection(db, "states");
const docRef = await addDoc(stateColl, mich);
console.debug("A new document added", docRef.id);
// Option #2: Set the content of a new (or existing) document
// Side Effect: this will create or overwrite the document
const michDocRef = doc(db, "states/MI");
const miOut = await setDoc(michDocRef, mich);
const florDocRef = doc(db, "states/FL");
await setDoc(florDocRef, flor);
console.debug("Done adding/overwriting a (new) document");
// Don't call process.exit() in a real application!
process.exit(0);
import { initializeApp } from "firebase/app";
import { cs371_demo_config } from "./my_fb_config";
import { State } from "./00-types";
import {
collection,
doc,
getDoc,
getDocs,
getFirestore,
} from "firebase/firestore";
// Initialize Firebase (Do this only once through your web app)
const app = initializeApp(cs371_demo_config);
const db = getFirestore();
// Option #1: Read a specific document
// requires the DocID: "MI" in the snippet below
const michDocRef = doc(db, "states/MI");
const miSnapshot = await getDoc(michDocRef);
if (miSnapshot.exists()) {
const miState = miSnapshot.data() as State;
console.debug("Retrieved document ID", miSnapshot.id);
console.debug("Doc content", miState);
}
// Option #2: Fetch all the documents in a collection
const stateColl = collection(db, "states");
const querySnapshot = await getDocs(stateColl);
querySnapshot.forEach((qds) => {
if (qds.exists()) {
const aState = qds.data() as State;
console.debug(`DocID: ${qds.id} Name: ${aState.name}`);
}
});
// Without a forced exit, NodeJS waits too long
process.exit(0);
import { initializeApp } from "firebase/app";
import { cs371_demo_config } from "./my_fb_config";
import {
arrayUnion,
doc,
getFirestore,
increment,
setDoc,
updateDoc,
} from "firebase/firestore";
// Initialize Firebase (Do this only once through your web app)
const app = initializeApp(cs371_demo_config);
const db = getFirestore();
// Option #1: Update a specific field in an existing document
// requires the DocID: "MI" in the snippet below
const michDocRef = doc(db, "states/MI");
await updateDoc(michDocRef, {
population: 10_500_000,
});
// Option #1a: Increment numeric fields
await updateDoc(michDocRef, {
population: increment(999),
});
// Option #1b: Append new value to an array field
await updateDoc(michDocRef, {
// Use arrayRemove to remove an item from an array field
nationalParks: arrayUnion(
"Pictured Rocks Natl. Park",
"HoffMaster State Park"
),
});
// Option #2: Add a new field(s) to an existing document
await setDoc(
michDocRef,
{
area: 96_716, // sq-miles
nickName: "Wolverine State",
},
{ merge: true }
);
// Without a forced exit, NodeJS waits too long
process.exit(0);
import { initializeApp } from "firebase/app";
import { cs371_demo_config } from "./my_fb_config";
import {
arrayRemove,
arrayUnion,
collection,
deleteDoc,
deleteField,
doc,
getDocs,
getFirestore,
QueryDocumentSnapshot,
QuerySnapshot,
setDoc,
updateDoc,
} from "firebase/firestore";
// Initialize Firebase (Do this only once through your web app)
const app = initializeApp(cs371_demo_config);
const db = getFirestore();
// Option #1: Delete a specific document
// requires the DocID: "MI" in the snippet below
const michDocRef = doc(db, "states/MI");
await deleteDoc(michDocRef);
// Option #2: Delete a specific field
const flDoc = doc(db, "states/FL");
await updateDoc(flDoc, {
population: deleteField(),
});
// Option #3: Delete an item from an array field
await updateDoc(flDoc, {
// Use arrayRemove to remove an item from an array field
nationalParks: arrayRemove("Everglades National Park"),
});
// Option #4: Delete ALL documents in a collection
const stateColl = collection(db, "states");
const qs = await getDocs(stateColl);
// Iterate over each document
qs.forEach(async (qd: QueryDocumentSnapshot) => {
console.info("Attempt to delete", qd.id);
// deleteDoc(doc(stateColl, qd.id));
});
// Cannot call process.exit(), otherwise the removal is incomplete
// process.exit(0);
import { initializeApp } from "firebase/app";
import { cs371_demo_config } from "./my_fb_config";
import { City, State } from "./00-types";
import {
addDoc,
collection,
doc,
getFirestore,
setDoc,
updateDoc,
} from "firebase/firestore";
// Initialize Firebase (Do this only once through your web app)
const app = initializeApp(cs371_demo_config);
const db = getFirestore();
const gr: City = {
name: "Grand Rapids",
population_per_sqmile: 4_235,
};
const holland: City = {
name: "Holland",
population_per_sqmile: 1_992,
};
// CREATE: Add a new document to a (new or existing) subcollection
const miCitiesColl = collection(db, "states/MI/cities");
let docRef = await addDoc(miCitiesColl, gr);
console.debug("A new document added", docRef.id);
docRef = await addDoc(miCitiesColl, holland);
const miAirportColl = collection(db, "states/MI/airports");
const GRRdoc = doc(miAirportColl, "GRR");
await setDoc(GRRdoc, {
name: "Gerald Ford International Airport",
runways: ["08R/26L", "08L/26R", "17/35"],
});
// Update
updateDoc(GRRdoc, {
public: true,
});
// Don't call process.exit() in a real application!
process.exit(0);

Setup Your Computer for running TypeScript on CLI

  1. Create a new directory first-firestore and then change your current directory there

  2. Initialize a Node project (do the following while you are inside the new directory created in (#1))

    yarn init
    #npm init
    
  3. Update package.json to enable ES6 module import/export

    {
      "type": "module",
    }
    
  4. Add typescript as a new project dependency

    yarn add typescript     # TS compiler
    yarn add tsx            # TS execution environment for NodeJS
    
  5. Install TypeScript globally

    yarn global add typescript
    # npm install -g typescript
    
  6. Create tsconfig.json:

    {
       "compilerOptions": {
          "target": "ESNext",
          "module": "ESNext",
          "sourceMap": true
       }
    }

    To enable top-level await:

    • target must be set to "ES2017" or higher
    • module must be set to "ES2022" or higher
  7. Create a "Hello World" program in TypeScript

    // hello.ts
    console.info("Hello world!")
  8. Run the above program

    npx tsx hello.ts

Setup Firebase Project (https://firebase.google.com)

  1. Create a new Project

    • Initialize a new Firestore
    • Create a new Web App under the project created in (#1)
  2. Add Firebase as another dependency to project in (#1)

    yarn add firebase
    yarn list firebase  # Optional: confirm version 11.x (or newer)
    
  3. Run each sample program

    npx tsx 01-hello-firestore.ts
    
export const cs371_demo_config = {
// Replace the following with your own project details
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
};
{
"name": "firebase-firestore",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"firebase": "^11.3.1",
"tsx": "^4.19.3",
"typescript": "^5.7.3"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment