From 21b4935387b8dcc63eff9a87c36d1e4303034b5d Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 24 Jul 2020 15:27:21 +0100 Subject: [PATCH 01/22] Functions snippets vNext --- functions/.gitignore | 1 + functions/emulator-suite.js | 8 -------- functions/package.json | 10 ++++++++-- functions/src/emulator-suite.js | 25 +++++++++++++++++++++++++ functions/src/index.js | 1 + 5 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 functions/.gitignore delete mode 100644 functions/emulator-suite.js create mode 100644 functions/src/emulator-suite.js create mode 100644 functions/src/index.js diff --git a/functions/.gitignore b/functions/.gitignore new file mode 100644 index 00000000..1521c8b7 --- /dev/null +++ b/functions/.gitignore @@ -0,0 +1 @@ +dist diff --git a/functions/emulator-suite.js b/functions/emulator-suite.js deleted file mode 100644 index 5909b58e..00000000 --- a/functions/emulator-suite.js +++ /dev/null @@ -1,8 +0,0 @@ -const firebase = require("firebase"); -require("firebase/functions"); - -function emulatorSettings() { - // [START functions_emulator_connect] - firebase.functions().useFunctionsEmulator("http://localhost:5001") - // [END functions_emulator_connect] -} diff --git a/functions/package.json b/functions/package.json index fbdb2c70..510d4c38 100644 --- a/functions/package.json +++ b/functions/package.json @@ -1,9 +1,15 @@ { "name": "functions", "version": "1.0.0", - "scripts": {}, + "scripts": { + "build": "webpack" + }, "license": "Apache-2.0", "dependencies": { - "firebase": "^7.17.1" + "firebase": "^0.800.3" + }, + "devDependencies": { + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12" } } diff --git a/functions/src/emulator-suite.js b/functions/src/emulator-suite.js new file mode 100644 index 00000000..9088158f --- /dev/null +++ b/functions/src/emulator-suite.js @@ -0,0 +1,25 @@ +import { initializeApp, getApp } from "@firebase/app"; +import { getFunctions, useFunctionsEmulator, httpsCallable } from "@firebase/functions"; + +initializeApp({ + projectId: '### CLOUD FUNCTIONS PROJECT ID ###', + apiKey: '### FIREBASE API KEY ###', + authDomain: '### FIREBASE AUTH DOMAIN ###', +}); + +export function emulatorSettings() { + // [START functions_emulator_connect] + const functions = getFunctions(getApp()); + useFunctionsEmulator(functions, "http://localhost:5001"); + // [END functions_emulator_connect] +} + +export function callFunction() { + // [START functions_callable_call] + const addMessage = httpsCallable(getFunctions(getApp()), 'addMessage'); + addMessage({ text: ''}).then((result) => { + const sanitizedMessage = result.data.text; + // ... + }); + // [END functions_callable_call] +} diff --git a/functions/src/index.js b/functions/src/index.js new file mode 100644 index 00000000..8b7043a7 --- /dev/null +++ b/functions/src/index.js @@ -0,0 +1 @@ +import "./emulator-suite"; From 7c999776eafec7c974ce30ebcfade8c70c0db85c Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 1 Sep 2020 16:33:26 +0100 Subject: [PATCH 02/22] Clean up functions --- functions/src/emulator-suite.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/functions/src/emulator-suite.js b/functions/src/emulator-suite.js index 9088158f..3b4fd9b0 100644 --- a/functions/src/emulator-suite.js +++ b/functions/src/emulator-suite.js @@ -14,12 +14,13 @@ export function emulatorSettings() { // [END functions_emulator_connect] } -export function callFunction() { +export async function callFunction() { // [START functions_callable_call] - const addMessage = httpsCallable(getFunctions(getApp()), 'addMessage'); - addMessage({ text: ''}).then((result) => { - const sanitizedMessage = result.data.text; - // ... - }); + const functions = getFunctions(getApp()); + const addMessage = httpsCallable(functions, 'addMessage'); + + const result = await addMessage({ text: ''}); + const sanitizedMessage = result.data.text; + // ... // [END functions_callable_call] } From 4d88eb93d47111088ad04127b6d9e22edb83b6f7 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 1 Sep 2020 18:01:23 +0100 Subject: [PATCH 03/22] Checkpoint --- firestore/emulator-suite.js | 5 +- firestore/package.json | 2 +- firestore/test.firestore.js | 310 ++++++++++++++++++------------------ 3 files changed, 159 insertions(+), 158 deletions(-) diff --git a/firestore/emulator-suite.js b/firestore/emulator-suite.js index 87b8f50d..e7b911ef 100644 --- a/firestore/emulator-suite.js +++ b/firestore/emulator-suite.js @@ -1,10 +1,9 @@ -const firebase = require('firebase'); -require('firebase/firestore'); +import { getFirestore } from "@firebase/firestore"; function onDocumentReady(firebaseApp) { //[START fs_emulator_connect] // Firebase previously initialized using firebase.initializeApp(). - var db = firebase.firestore(); + const db = getFirestore(firebaseApp); if (location.hostname === "localhost") { db.settings({ host: "localhost:8080", diff --git a/firestore/package.json b/firestore/package.json index 3e2d7419..eab5be9e 100644 --- a/firestore/package.json +++ b/firestore/package.json @@ -4,6 +4,6 @@ "scripts": {}, "license": "Apache-2.0", "dependencies": { - "firebase": "^7.17.1" + "firebase": "^0.800.7" } } diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index 9fe4bd4b..77b05ed2 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -1,34 +1,41 @@ +import { initializeApp } from "@firebase/app"; +import { getFirestore } from "@firebase/firestore"; + describe("firestore", () => { - var db; + let db; before(() => { - var config = { + const config = { apiKey: "AIzaSyCM61mMr_iZnP1DzjT1PMB5vDGxfyWNM64", authDomain: "firestore-snippets.firebaseapp.com", projectId: "firestore-snippets" }; - var app = firebase.initializeApp(config); - db = firebase.firestore(app); + const app = initializeApp(config); + db = getFirestore(app); //firebase.firestore.setLogLevel("debug"); }); it("should be able to set the cache size", () => { // [START fs_setup_cache] - firebase.firestore().settings({ + db.settings({ cacheSizeBytes: firebase.firestore.CACHE_SIZE_UNLIMITED }); // [END fs_setup_cache] }); it("should be initializable with persistence", () => { - firebase.initializeApp({ + const app = initializeApp({ apiKey: '### FIREBASE API KEY ###', authDomain: '### FIREBASE AUTH DOMAIN ###', projectId: '### CLOUD FIRESTORE PROJECT ID ###', } ,"persisted_app"); + const db = getFirestore(app); + // [START initialize_persistence] - firebase.firestore().enablePersistence() - .catch(function(err) { + const { enableIndexedDbPersistence } = require("@firebase/firestore"); + + enableIndexedDbPersistence(db) + .catch((err) => { if (err.code == 'failed-precondition') { // Multiple tabs open, persistence can only be enabled // in one tab at a a time. @@ -43,109 +50,108 @@ describe("firestore", () => { // [END initialize_persistence] }); - it("should be able to enable/disable network", () => { - var disable = - // [START disable_network] - firebase.firestore().disableNetwork() - .then(function() { - // Do offline actions - // [START_EXCLUDE] - console.log("Network disabled!"); - // [END_EXCLUDE] - }); - // [END disable_network] + it("should be able to enable/disable network", async () => { + // [START disable_network] + const { disableNetwork } = require("@firebase/firestore"); - var enable = - // [START enable_network] - firebase.firestore().enableNetwork() - .then(function() { - // Do online actions - // [START_EXCLUDE] - console.log("Network enabled!"); - // [END_EXCLUDE] - }); - // [END enable_network] + await disableNetwork(db); + console.log("Network disabled!"); + // Do offline actions + // [START_EXCLUDE] + console.log("Network disabled!"); + // [END_EXCLUDE] + // [END disable_network] + + // [START enable_network] + const { enableNetwork } = require("@firebase/firestore"); + + await enableNetwork(db) + // Do online actions + // [START_EXCLUDE] + console.log("Network enabled!"); + // [END_EXCLUDE] + // [END enable_network] - return Promise.all([enable, disable]); }); it("should reply with .fromCache fields", () => { // [START use_from_cache] - db.collection("cities").where("state", "==", "CA") - .onSnapshot({ includeMetadataChanges: true }, function(snapshot) { - snapshot.docChanges().forEach(function(change) { - if (change.type === "added") { - console.log("New city: ", change.doc.data()); - } + const { collection, onSnapshot, where, query } = require("@firebase/firestore"); + + const query = query(collection(db, "cities"), where("state", "==", "CA")); + onSnapshot(query, { includeMetadataChanges: true }, (snapshot) => { + snapshot.docChanges().forEach((change) => { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } - var source = snapshot.metadata.fromCache ? "local cache" : "server"; - console.log("Data came from " + source); - }); - }); + const source = snapshot.metadata.fromCache ? "local cache" : "server"; + console.log("Data came from " + source); + }); + }); // [END use_from_cache] }); describe("collection('users')", () => { - it("should add data to a collection", () => { - return output = + it("should add data to a collection", async () => { // [START add_ada_lovelace] - db.collection("users").add({ + const { collection, addDoc } = require("@firebase/firestore"); + + try { + const docRef = await addDoc(collection(db, "users"), { first: "Ada", last: "Lovelace", born: 1815 - }) - .then(function(docRef) { - console.log("Document written with ID: ", docRef.id); - }) - .catch(function(error) { - console.error("Error adding document: ", error); - }); + }); + console.log("Document written with ID: ", docRef.id); + } catch (e) { + console.error("Error adding document: ", e); + } // [END add_ada_lovelace] }); - it("should get all users", () => { - return output = + it("should get all users", async () => { // [START get_all_users] - db.collection("users").get().then((querySnapshot) => { - querySnapshot.forEach((doc) => { - console.log(`${doc.id} => ${doc.data()}`); - }); + const { getDocs } = require("@firebase/firestore"); + + const querySnapshot = await getDocs(db.collection("users")); + querySnapshot.forEach((doc) => { + console.log(`${doc.id} => ${doc.data()}`); }); // [END get_all_users] }); - it("should add data to a collection with new fields", () => { - return output = + it("should add data to a collection with new fields", async () => { // [START add_alan_turing] // Add a second document with a generated ID. - db.collection("users").add({ + const { addDoc, collection } = require("@firebase/firestore"); + + try { + const docRef = await addDoc(collection(db, "users"), { first: "Alan", middle: "Mathison", last: "Turing", born: 1912 - }) - .then(function(docRef) { - console.log("Document written with ID: ", docRef.id); - }) - .catch(function(error) { - console.error("Error adding document: ", error); - }); + }); + + console.log("Document written with ID: ", docRef.id); + } catch (e) { + console.error("Error adding document: ", e); + } // [END add_alan_turing] }); it("should loop through a watched collection", (done) => { - // This is not a typo. - var unsubscribe = - // [START listen_for_users] - db.collection("users") - .where("born", "<", 1900) - .onSnapshot(function(snapshot) { - console.log("Current users born before 1900:"); - snapshot.forEach(function (userSnapshot) { - console.log(userSnapshot.data()) - }); + const { collection, where, query, onSnapshot } = require("@firebase/firestore"); + + const q = query(collection(db, "users"), where("born", "<", 1900)); + const unsubscribe = onSnapshot(q, (snapshot) => { + console.log("Current users born before 1900:"); + snapshot.forEach(function (userSnapshot) { + console.log(userSnapshot.data()) }); + }); // [END listen_for_users] setTimeout(() => { @@ -156,48 +162,50 @@ describe("firestore", () => { it("should reference a specific document", () => { // [START doc_reference] - var alovelaceDocumentRef = db.collection('users').doc('alovelace'); + const { collection, doc } = require("@firebase/firestore"); + + const alovelaceDocumentRef = doc(collection(db, 'users'), 'alovelace'); // [END doc_reference] }); it("should reference a specific collection", () => { // [START collection_reference] - var usersCollectionRef = db.collection('users'); + const { collection } = require("@firebase/firestore"); + + const usersCollectionRef = collection(db, 'users'); // [END collection_reference] }); it("should reference a specific document (alternative)", () => { // [START doc_reference_alternative] - var alovelaceDocumentRef = db.doc('users/alovelace'); + const { doc } = require("@firebase/firestore"); + + const alovelaceDocumentRef = doc(db, 'users/alovelace'); // [END doc_reference_alternative] }) it("should reference a document in a subcollection", () => { // [START subcollection_reference] - var messageRef = db.collection('rooms').doc('roomA') - .collection('messages').doc('message1'); + const { doc, collection } = require("@firebase/firestore"); + + const messageRef = doc(collection(doc(collection("rooms"), "roomA"), "messages"), "message1"); // [END subcollection_reference] }); - it("should set a document", () => { - return output = + it("should set a document", async () => { // [START set_document] + const { doc, collection, setDoc } = require("@firebase/firestore"); + // Add a new document in collection "cities" - db.collection("cities").doc("LA").set({ - name: "Los Angeles", - state: "CA", - country: "USA" - }) - .then(function() { - console.log("Document successfully written!"); - }) - .catch(function(error) { - console.error("Error writing document: ", error); + await setDoc(doc(collection(db, "cities"), "LA"), { + name: "Los Angeles", + state: "CA", + country: "USA" }); // [END set_document] }); - it("should set document with a custom object converter", () => { + it("should set document with a custom object converter", async () => { // [START city_custom_object] class City { constructor (name, state, country ) { @@ -210,78 +218,76 @@ describe("firestore", () => { } } - // Firestore data converter - cityConverter = { - toFirestore: function(city) { - return { - name: city.name, - state: city.state, - country: city.country - } - }, - fromFirestore: function(snapshot, options){ - const data = snapshot.data(options); - return new City(data.name, data.state, data.country) - } - } + // Firestore data converter + cityConverter = { + toFirestore: function(city) { + return { + name: city.name, + state: city.state, + country: city.country + } + }, + fromFirestore: function(snapshot, options){ + const data = snapshot.data(options); + return new City(data.name, data.state, data.country) + } + } // [END city_custom_object] - return output = // [START set_custom_object] + const { doc, collection, setDoc } = require("@firebase/firestore"); + // Set with cityConverter - db.collection("cities").doc("LA") - .withConverter(cityConverter) - .set(new City("Los Angeles", "CA", "USA")); + const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); + await setDoc(ref, new City("Los Angeles", "CA", "USA")); // [END set_custom_object] }); - it("should get document with a custom object converter", () => { - return output = + it("should get document with a custom object converter", async () => { // [START get_custom_object] - db.collection("cities").doc("LA") - .withConverter(cityConverter) - .get().then(function(doc) { - if (doc.exists){ - // Convert to City object - city = doc.data(); - // Use a City instance method - console.log(city.toString()); - } else { - console.log("No such document!") - }}).catch(function(error) { - console.log("Error getting document:", error) - }); + const { doc, collection, getDoc} = require("@firebase/firestore"); + + const ref = collection(doc(db, "cities"), "LA").withConverter(cityConverter); + const doc = await getDoc(ref); + if (doc.exists){ + // Convert to City object + city = doc.data(); + // Use a City instance method + console.log(city.toString()); + } else { + console.log("No such document!") + } // [END get_custom_object] }); - it("should support batch writes", (done) => { + it("should support batch writes", async () => { // [START write_batch] + const { writeBatch, doc, collection } = require("@firebase/firestore"); + // Get a new write batch - var batch = db.batch(); + const batch = writeBatch(db); // Set the value of 'NYC' - var nycRef = db.collection("cities").doc("NYC"); + const nycRef = doc(collection(db, "cities"), "NYC"); batch.set(nycRef, {name: "New York City"}); // Update the population of 'SF' - var sfRef = db.collection("cities").doc("SF"); + const sfRef = doc(collection(db, "cities"), "SF"); batch.update(sfRef, {"population": 1000000}); // Delete the city 'LA' - var laRef = db.collection("cities").doc("LA"); + const laRef = doc(collection(db, "cities"), "LA"); batch.delete(laRef); // Commit the batch - batch.commit().then(function () { - // [START_EXCLUDE] - done(); - // [END_EXCLUDE] - }); + await batch.commit(); // [END write_batch] }); - it("should set a document with every datatype #UNVERIFIED", () => { + it("should set a document with every datatype #UNVERIFIED", async () => { // [START data_types] - var docData = { + const { doc, collection, setDoc } = require("@firebase/firestore"); + + const docData = { stringExample: "Hello world!", booleanExample: true, numberExample: 3.14159265, @@ -295,40 +301,36 @@ describe("firestore", () => { } } }; - db.collection("data").doc("one").set(docData).then(function() { - console.log("Document successfully written!"); - }); + await setDoc(doc(collection(db, "data"), "one"), docData); // [END data_types] }); - it("should allow set with merge", () => { + it("should allow set with merge", async () => { // [START set_with_merge] - var cityRef = db.collection('cities').doc('BJ'); + const { doc, collection, setDoc } = require("@firebase/firestore"); - var setWithMerge = cityRef.set({ - capital: true - }, { merge: true }); + const cityRef = doc(collection(db, 'cities'), 'BJ'); + setDoc(cityRef, { capital: true }, { merge: true }); // [END set_with_merge] return setWithMerge; }); - it("should update a document's nested fields #UNVERIFIED", () => { + it("should update a document's nested fields #UNVERIFIED", async () => { // [START update_document_nested] + const { doc, collection, setDoc, updateDoc } = require("@firebase/firestore"); + // Create an initial document to update. - var frankDocRef = db.collection("users").doc("frank"); - frankDocRef.set({ + const frankDocRef = doc(collection(db, "users"), "frank"); + await setDoc(frankDocRef, { name: "Frank", favorites: { food: "Pizza", color: "Blue", subject: "recess" }, age: 12 }); // To update age and favorite color: - db.collection("users").doc("frank").update({ + await updateDoc(frankDocRef, { "age": 13, "favorites.color": "Red" - }) - .then(function() { - console.log("Document successfully updated!"); }); // [END update_document_nested] }); From 3729cff73438cb4a96e2c791fa49bf2b3c00eea2 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Sep 2020 11:30:47 +0100 Subject: [PATCH 04/22] Another checkpoint --- firestore/test.firestore.js | 492 ++++++++++++++++++------------------ 1 file changed, 242 insertions(+), 250 deletions(-) diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index 77b05ed2..ad55d050 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -248,7 +248,7 @@ describe("firestore", () => { const ref = collection(doc(db, "cities"), "LA").withConverter(cityConverter); const doc = await getDoc(ref); - if (doc.exists){ + if (doc.exists) { // Convert to City object city = doc.data(); // Use a City instance method @@ -341,277 +341,265 @@ describe("firestore", () => { * Delete a collection, in batches of batchSize. Note that this does * not recursively delete subcollections of documents in the collection */ + const { query, orderBy, limit, getDocs, writeBatch } = require("@firebase/firestore"); + function deleteCollection(db, collectionRef, batchSize) { - var query = collectionRef.orderBy('__name__').limit(batchSize); + const q = query(collectionRef, orderBy('__name__'), limit(batchSize)) - return new Promise(function(resolve, reject) { - deleteQueryBatch(db, query, batchSize, resolve, reject); - }); + return new Promise(function(resolve) { + deleteQueryBatch(db, q, batchSize, resolve); + }); } - function deleteQueryBatch(db, query, batchSize, resolve, reject) { - query.get() - .then((snapshot) => { - // When there are no documents left, we are done - if (snapshot.size == 0) { - return 0; - } + async function deleteQueryBatch(db, query, batchSize, resolve) { + const snapshot = await getDocs(query); - // Delete documents in a batch - var batch = db.batch(); - snapshot.docs.forEach(function(doc) { - batch.delete(doc.ref); - }); + // When there are no documents left, we are done + let numDeleted = 0; + if (snapshot.size > 0) { + // Delete documents in a batch + const batch = writeBatch(db); + snapshot.docs.forEach((doc) => { + batch.delete(doc.ref); + }); - return batch.commit().then(function() { - return snapshot.size; - }); - }).then(function(numDeleted) { - if (numDeleted < batchSize) { - resolve(); - return; - } + await batch.commit(); + numDeleted = snapshot.size; + } - // Recurse on the next process tick, to avoid - // exploding the stack. - setTimeout(function() { - deleteQueryBatch(db, query, batchSize, resolve, reject); - }, 0); - }) - .catch(reject); + if (numDeleted < batchSize) { + resolve(); + return; + } + + // Recurse on the next process tick, to avoid + // exploding the stack. + setTimeout(() => { + deleteQueryBatch(db, query, batchSize, resolve); + }, 0); } // [END delete_collection] - return deleteCollection(db, db.collection("users"), 2); + return deleteCollection(db, collecton(db, "users"), 2); }).timeout(2000); }); describe("collection('cities')", () => { - it("should set documents #UNVERIFIED", () => { + it("should set documents", async () => { // [START example_data] - var citiesRef = db.collection("cities"); + const { collection, doc, setDoc } = require("@firebase/firestore"); + + const citiesRef = collection(db, "cities"); - citiesRef.doc("SF").set({ + await setDoc(doc(citiesRef, "SF"), { name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); - citiesRef.doc("LA").set({ + await setDoc(doc(citiesRef, "LA"), { name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); - citiesRef.doc("DC").set({ + await setDoc(doc(citiesRef, "DC"), { name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); - citiesRef.doc("TOK").set({ + await setDoc(doc(citiesRef, "TOK"), { name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); - citiesRef.doc("BJ").set({ + await setDoc(doc(citiesRef, "BJ"), { name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] }); // [END example_data] }); - it("should set a document", () => { - var data = {}; + it("should set a document", async () => { + const data = {}; - return output = // [START cities_document_set] - db.collection("cities").doc("new-city-id").set(data); + const { collection, doc, setDoc } = require("@firebase/firestore"); + + await setDoc(doc(collection("cities"), "new-city-id"), data); // [END cities_document_set] }); - it("should add a document", () => { - return output = + it("should add a document", async () => { // [START add_document] + const { collection, addDoc } = require("@firebase/firestore"); + // Add a new document with a generated id. - db.collection("cities").add({ - name: "Tokyo", - country: "Japan" - }) - .then(function(docRef) { - console.log("Document written with ID: ", docRef.id); - }) - .catch(function(error) { - console.error("Error adding document: ", error); + const docRef = await addDoc(collection(db, "cities"), { + name: "Tokyo", + country: "Japan" }); + console.log("Document written with ID: ", docRef.id); // [END add_document] }); - it("should add an empty a document #UNVERIFIED", () => { - var data = {}; + it("should add an empty a document", async () => { + const data = {}; // [START new_document] - // Add a new document with a generated id. - var newCityRef = db.collection("cities").doc(); + const { collection, doc, setDoc } = require("@firebase/firestore"); + + // Add a new document with a generated id + const newCityRef = doc(collection(db, "cities")); // later... - newCityRef.set(data); + await setDoc(newCityRef, data); // [END new_document] }); - it("should update a document", () => { - var data = {}; + it("should update a document", async () => { + const data = {}; // [START update_document] - var washingtonRef = db.collection("cities").doc("DC"); + const { collection, doc, updateDoc } = require("@firebase/firestore"); + + const washingtonRef = doc(collection(db, "cities"), "DC"); // Set the "capital" field of the city 'DC' - return washingtonRef.update({ - capital: true - }) - .then(function() { - console.log("Document successfully updated!"); - }) - .catch(function(error) { - // The document probably doesn't exist. - console.error("Error updating document: ", error); + await updateDoc(washingtonRef, { + capital: true }); // [END update_document] }); - it("should update an array field in a document", () => { + it("should update an array field in a document", async () => { // [START update_document_array] - var washingtonRef = db.collection("cities").doc("DC"); + const { collection, doc, updateDoc, arrayUnion, arrayRemove } = require("@firebase/firestore"); + + const washingtonRef = doc(collection("db", cities), "DC"); // Atomically add a new region to the "regions" array field. - washingtonRef.update({ - regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia") + await updateDoc(washingtonRef, { + regions: arrayUnion("greater_virginia") }); // Atomically remove a region from the "regions" array field. - washingtonRef.update({ - regions: firebase.firestore.FieldValue.arrayRemove("east_coast") + await updateDoc(washingtonRef, { + regions: arrayRemove("east_coast") }); // [END update_document_array] }); - it("should update a document using numeric transforms", () => { + it("should update a document using numeric transforms", async () => { // [START update_document_increment] - var washingtonRef = db.collection('cities').doc('DC'); + const { collection, doc, updateDoc, increment } = require("@firebase/firestore"); + + const washingtonRef = doc(collection("db", cities), "DC"); // Atomically increment the population of the city by 50. - washingtonRef.update({ - population: firebase.firestore.FieldValue.increment(50) + await updateDoc(washingtonRef, { + population: increment(50) }); // [END update_document_increment] }) - it("should delete a document", () => { - return output = + it("should delete a document", async () => { // [START delete_document] - db.collection("cities").doc("DC").delete().then(function() { - console.log("Document successfully deleted!"); - }).catch(function(error) { - console.error("Error removing document: ", error); - }); + const { collection, doc, deleteDoc } = require("@firebase/firestore"); + + await deleteDoc(doc(collection(db, "cities"), "DC")); // [END delete_document] }); - it("should handle transactions #FIXME #UNVERIFIED", () => { - return db.collection("cities").doc("SF").set({ population: 0 }).then(() => { - // [START transaction] - // Create a reference to the SF doc. - var sfDocRef = db.collection("cities").doc("SF"); + it("should handle transactions", async () => { + const { collection, doc, setDoc } = require("@firebase/firestore"); - // Uncomment to initialize the doc. - // sfDocRef.set({ population: 0 }); + const sfDocRef = doc(collection(db, "cities"), "SF"); + await setDoc(sfDocRef, { population: 0 }); - return db.runTransaction(function(transaction) { - // This code may get re-run multiple times if there are conflicts. - return transaction.get(sfDocRef).then(function(sfDoc) { - if (!sfDoc.exists) { - throw "Document does not exist!"; - } + // [START transaction] + const { runTransaction } = require("@firebase/firestore"); - // Add one person to the city population. - // Note: this could be done without a transaction - // by updating the population using FieldValue.increment() - var newPopulation = sfDoc.data().population + 1; - transaction.update(sfDocRef, { population: newPopulation }); - }); - }).then(function() { - console.log("Transaction successfully committed!"); - }).catch(function(error) { - console.log("Transaction failed: ", error); - }); - // [END transaction] - }); + try { + await runTransaction(db, async (transaction) => { + const sfDoc = await transaction.get(sfDocRef); + if (!sfDoc.exists()) { + throw "Document does not exist!"; + } + + const newPopulation = sfDoc.data().population + 1; + transaction.update(sfDocRef, { population: newPopulation }); + }); + console.log("Transaction successfully committed!"); + } catch (e) { + console.log("Transaction failed: ", e); + } + // [END transaction] }); - it("should handle transaction which bubble out data #UNVERIFIED", () => { + it("should handle transaction which bubble out data", async () => { // [START transaction_promise] + const { collection, doc, runTransaction } = require("@firebase/firestore"); + // Create a reference to the SF doc. - var sfDocRef = db.collection("cities").doc("SF"); + const sfDocRef = doc(collection(db, "cities"), "SF"); - db.runTransaction(function(transaction) { - return transaction.get(sfDocRef).then(function(sfDoc) { - if (!sfDoc.exists) { - throw "Document does not exist!"; - } + try { + const newPopulation = await runTransaction(db, (transaction) => { + const sfDoc = await transaction.get(sfDocRef); + if (!sfDoc.exists()) { + throw "Document does not exist!"; + } - var newPopulation = sfDoc.data().population + 1; - if (newPopulation <= 1000000) { - transaction.update(sfDocRef, { population: newPopulation }); - return newPopulation; - } else { - return Promise.reject("Sorry! Population is too big."); - } - }); - }).then(function(newPopulation) { - console.log("Population increased to ", newPopulation); - }).catch(function(err) { - // This will be an "population is too big" error. - console.error(err); - }); + const newPop = sfDoc.data().population + 1; + if (newPop <= 1000000) { + transaction.update(sfDocRef, { population: newPop }); + } else { + return Promise.reject("Sorry! Population is too big"); + } + }); + + console.log("Population increased to ", newPopulation); + } catch (e) { + // This will be a "population is too big" error. + console.error(e); + } // [END transaction_promise] }); - it("should get a single document #UNVERIFIED", () => { + it("should get a single document", async () => { // [START get_document] - var docRef = db.collection("cities").doc("SF"); + const { collection, doc, getDoc } = require("@firebase/firestore"); - docRef.get().then(function(doc) { - if (doc.exists) { - console.log("Document data:", doc.data()); - } else { - // doc.data() will be undefined in this case - console.log("No such document!"); - } - }).catch(function(error) { - console.log("Error getting document:", error); - }); + const docRef = doc(collection(db, "cities"), "SF"); + const doc = await getDoc(docRef); + + if (doc.exists) { + console.log("Document data:", doc.data()); + } else { + // doc.data() will be undefined in this case + console.log("No such document!"); + } // [END get_document] }); - it("should get a document with options #UNVERIFIED", () => { + it("should get a document with options", async () => { // [START get_document_options] - var docRef = db.collection("cities").doc("SF"); + const { collection, doc, getDocFromCache } = require("@firebase/firestore"); - // Valid options for source are 'server', 'cache', or - // 'default'. See https://firebase.google.com/docs/reference/js/firebase.firestore.GetOptions - // for more information. - var getOptions = { - source: 'cache' - }; + const docRef = doc(collection(db, "cities"), "SF"); // Get a document, forcing the SDK to fetch from the offline cache. - docRef.get(getOptions).then(function(doc) { - // Document was found in the cache. If no cached document exists, - // an error will be returned to the 'catch' block below. - console.log("Cached document data:", doc.data()); - }).catch(function(error) { - console.log("Error getting cached document:", error); - }); + try { + const doc = await getDocFromCache(docRef); + + // Document was found in the cache. If no cached document exists, + // an error will be returned to the 'catch' block below. + console.log("Cached document data:", doc.data()); + } catch (e) { + console.log("Error getting cached document:", e); + } // [END get_document_options] }); it("should listen on a single document", (done) => { - var unsub = // [START listen_document] - db.collection("cities").doc("SF") - .onSnapshot(function(doc) { - console.log("Current data: ", doc.data()); - }); + const { collection, doc, onSnapshot } = require("@firebase/firestore"); + + const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { + console.log("Current data: ", doc.data()); + }); // [END listen_document] setTimeout(function() { @@ -620,14 +608,14 @@ describe("firestore", () => { }, 3000); }).timeout(5000); - it("should listen on a single document with metadata #UNVERIFIED", (done) => { - var unsub = + it("should listen on a single document with metadata", (done) => { // [START listen_document_local] - db.collection("cities").doc("SF") - .onSnapshot(function(doc) { - var source = doc.metadata.hasPendingWrites ? "Local" : "Server"; - console.log(source, " data: ", doc.data()); - }); + const { collection, doc, onSnapshot } = require("@firebase/firestore"); + + const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { + const source = doc.metadata.hasPendingWrites ? "Local" : "Server"; + console.log(source, " data: ", doc.data()); + }); // [END listen_document_local] setTimeout(function() { @@ -637,15 +625,15 @@ describe("firestore", () => { }).timeout(5000); it("should listen on a single document with options #UNVERIFIED", (done) => { - var unsub = // [START listen_with_metadata] - db.collection("cities").doc("SF") - .onSnapshot({ - // Listen for document metadata changes - includeMetadataChanges: true - }, function(doc) { - // ... - }); + const { collection, doc, onSnapshot } = require("@firebase/firestore"); + + const unsub = onSnapshot( + doc(collection(db, "cities"), "SF"), + { includeMetadataChanges: true }, + (doc) => { + // ... + }); // [END listen_with_metadata] setTimeout(function() { @@ -654,46 +642,44 @@ describe("firestore", () => { }, 3000); }).timeout(5000); - it("should get multiple documents from a collection", () => { - return output = + it("should get multiple documents from a collection", async () => { // [START get_multiple] - db.collection("cities").where("capital", "==", true) - .get() - .then(function(querySnapshot) { - querySnapshot.forEach(function(doc) { - // doc.data() is never undefined for query doc snapshots - console.log(doc.id, " => ", doc.data()); - }); - }) - .catch(function(error) { - console.log("Error getting documents: ", error); - }); + const { collection, query, where, getDocs } = require("@firebase/firestore"); + + const q = query(collection(db, "cities"), where("capital", "==", true)); + + const querySnapshot = await getDocs(q); + querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); + }); // [END get_multiple] }).timeout(5000); - it("should get all documents from a collection", () => { - return output = + it("should get all documents from a collection", async () => { // [START get_multiple_all] - db.collection("cities").get().then(function(querySnapshot) { - querySnapshot.forEach(function(doc) { - // doc.data() is never undefined for query doc snapshots - console.log(doc.id, " => ", doc.data()); - }); + const { collection, getDocs } = require("@firebase/firestore"); + + const querySnapshot = await getDocs(collection(db, "cities")); + querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); }); // [END get_multiple_all] }) it("should listen on multiple documents #UNVERIFIED", (done) => { - var unsubscribe = // [START listen_multiple] - db.collection("cities").where("state", "==", "CA") - .onSnapshot(function(querySnapshot) { - var cities = []; - querySnapshot.forEach(function(doc) { - cities.push(doc.data().name); - }); - console.log("Current cities in CA: ", cities.join(", ")); - }); + const { collection, query, where, onSnapshot } = require("@firebase/firestore"); + + const q = query(collection(db, "cities"), where("state", "==", "CA")); + const unsubscribe = onSnapshot(q, (querySnapshot) => { + const cities = []; + querySnapshot.forEach((doc) => { + cities.push(doc.data().name); + }); + console.log("Current cities in CA: ", cities.join(", ")); + }); // [END listen_multiple] setTimeout(function() { unsubscribe(); @@ -702,22 +688,23 @@ describe("firestore", () => { }).timeout(5000); it("should view changes between snapshots #UNVERIFIED", (done) => { - var unsubscribe = // [START listen_diffs] - db.collection("cities").where("state", "==", "CA") - .onSnapshot(function(snapshot) { - snapshot.docChanges().forEach(function(change) { - if (change.type === "added") { - console.log("New city: ", change.doc.data()); - } - if (change.type === "modified") { - console.log("Modified city: ", change.doc.data()); - } - if (change.type === "removed") { - console.log("Removed city: ", change.doc.data()); - } - }); - }); + const { collection, query, where, onSnapshot } = require("@firebase/firestore"); + + const q = query(collection(db, "cities"), where("state", "==", "CA")); + const unsubscribe = onSnapshot(q, (snapshot) => { + snapshot.docChanges().forEach((change) => { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + if (change.type === "modified") { + console.log("Modified city: ", change.doc.data()); + } + if (change.type === "removed") { + console.log("Removed city: ", change.doc.data()); + } + }); + }); // [END listen_diffs] setTimeout(function() { unsubscribe(); @@ -727,11 +714,12 @@ describe("firestore", () => { it("should unsubscribe a listener", () => { // [START detach_listener] - var unsubscribe = db.collection("cities") - .onSnapshot(function (){ - // Respond to data - // ... - }); + const { collection, onSnapshot } = require("@firebase/firestore"); + + const unsubscribe = onSnapshot(collection(db, "cities"), () => { + // Respond to data + // ... + }); // Later ... @@ -741,38 +729,42 @@ describe("firestore", () => { }); it("should handle listener errors", () => { - var unsubscribe = // [START handle_listen_errors] - db.collection("cities") - .onSnapshot(function(snapshot) { - //... - }, function(error) { - //... - }); + const { collection, onSnapshot } = require("@firebase/firestore"); + + const unsubscribe = onSnapshot( + collection(db, "cities"), + (snapshot) => { + // ... + }, + (error) => { + // ... + }); // [END handle_listen_errors] unsubscribe(); }); - it("should update a document with server timestamp", () => { - function update() { + it("should update a document with server timestamp", async () => { + async function update() { // [START update_with_server_timestamp] - var docRef = db.collection('objects').doc('some-id'); + const { collection, updateDoc, serverTimestamp } = require("@firebase/firestore"); + + const docRef = doc(collection(db, 'objects'), 'some-id'); // Update the timestamp field with the value from the server - var updateTimestamp = docRef.update({ - timestamp: firebase.firestore.FieldValue.serverTimestamp() + const updateTimestamp = await updateDoc(docRef, { + timestamp: serverTimestamp() }); // [END update_with_server_timestamp] return updateTimestamp; } - return db.collection('objects').doc('some-id') - .set({}) - .then(() => update()) - .then(() => { - console.log('Document updated with server timestamp'); - }); + const { collection, doc, setDoc } = require("@firebase/firestore"); + + await setDoc(doc(collection(db, 'objects'), 'some-id'), {}); + await update(); + console.log('Document updated with server timestamp'); }); it("should use options to control server timestamp resolution #UNVERIFIED", () => { From ee83fe404968bc93bff481b5b6356a4d0d1a03c5 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Sep 2020 12:08:58 +0100 Subject: [PATCH 05/22] WOOOOOOOOT --- firestore/test.firestore.js | 455 ++++++++++++++++++++---------------- 1 file changed, 260 insertions(+), 195 deletions(-) diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index ad55d050..8591db6f 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -1,5 +1,5 @@ import { initializeApp } from "@firebase/app"; -import { getFirestore } from "@firebase/firestore"; +import { getFirestore, CACHE_SIZE_UNLIMITED } from "@firebase/firestore"; describe("firestore", () => { let db; @@ -11,13 +11,12 @@ describe("firestore", () => { }; const app = initializeApp(config); db = getFirestore(app); - //firebase.firestore.setLogLevel("debug"); }); it("should be able to set the cache size", () => { // [START fs_setup_cache] db.settings({ - cacheSizeBytes: firebase.firestore.CACHE_SIZE_UNLIMITED + cacheSizeBytes: CACHE_SIZE_UNLIMITED }); // [END fs_setup_cache] }); @@ -285,13 +284,13 @@ describe("firestore", () => { it("should set a document with every datatype #UNVERIFIED", async () => { // [START data_types] - const { doc, collection, setDoc } = require("@firebase/firestore"); + const { doc, collection, setDoc, Timestamp } = require("@firebase/firestore"); const docData = { stringExample: "Hello world!", booleanExample: true, numberExample: 3.14159265, - dateExample: firebase.firestore.Timestamp.fromDate(new Date("December 10, 1815")), + dateExample: Timestamp.fromDate(new Date("December 10, 1815")), arrayExample: [5, true, "hello"], nullExample: null, objectExample: { @@ -761,62 +760,63 @@ describe("firestore", () => { } const { collection, doc, setDoc } = require("@firebase/firestore"); - + await setDoc(doc(collection(db, 'objects'), 'some-id'), {}); await update(); console.log('Document updated with server timestamp'); }); - it("should use options to control server timestamp resolution #UNVERIFIED", () => { - var options = { - // Options: 'estimate', 'previous', or 'none' - serverTimestamps: 'estimate' - }; + it("should use options to control server timestamp resolution", async () => { + // [START server_timestamp_resolution_options] + const { collection, updateDoc, serverTimestamp, onSnapshot } = require("@firebase/firestore"); + // Perform an update followed by an immediate read without + // waiting for the update to complete. Due to the snapshot + // options we will get two results: one with an estimate + // timestamp and one with the resolved server timestamp. + const docRef = doc(collection(db, 'objects'), 'some-id'); + updateDoc(docRef, { + timestamp: serverTimestamp() + }); - // Perform an update followed by an immediate read without - // waiting for the update to complete. Due to the snapshot - // options we will get two results: one with an estimate - // timestamp and one with the resolved server timestamp. - var docRef = db.collection('objects').doc('some-id'); - docRef.update({ - timestamp: firebase.firestore.FieldValue.serverTimestamp() - }); - docRef.onSnapshot(function(snapshot) { - var data = snapshot.data(options); - console.log( - 'Timestamp: ' + data.timestamp + - ', pending: ' + snapshot.metadata.hasPendingWrites); - }); + onSnapshot(docRef, (snapshot) => { + const options = { + // Options: 'estimate', 'previous', or 'none' + serverTimestamps: 'estimate' + }; + const data = snapshot.data(options); + console.log( + 'Timestamp: ' + data.timestamp + + ', pending: ' + snapshot.metadata.hasPendingWrites); + }); + // [END server_timestamp_resolution_options] }); - it("should delete a document field", () => { - function update() { - // [START update_delete_field] - var cityRef = db.collection('cities').doc('BJ'); + it("should delete a document field", async () => { + async function update() { + // [START update_delete_field] + const { doc, collection, updateDoc, deleteField } = require("@firebase/firestore"); - // Remove the 'capital' field from the document - var removeCapital = cityRef.update({ - capital: firebase.firestore.FieldValue.delete() - }); - // [END update_delete_field] + const cityRef = doc(collection(db, 'cities'), 'BJ'); - return removeCapital; + // Remove the 'capital' field from the document + await updateDoc(cityRef, { + capital: deleteField() + }); + // [END update_delete_field] } + const { doc, collection, setDoc } = require("@firebase/firestore"); - return db.collection('cities').doc('BJ') - .set({ capital: true }) - .then(() => update()) - .then(() => { - console.log('Document field deleted'); - }); + await setDoc(doc(collection(db,'cities'), 'BJ'), { capital: true }); + await update(); }); describe("queries", () => { it("should handle simple where", () => { // [START simple_queries] // Create a reference to the cities collection - var citiesRef = db.collection("cities"); + const { collection, query, where } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); // Create a query against the collection. var query = citiesRef.where("state", "==", "CA"); @@ -825,242 +825,306 @@ describe("firestore", () => { it("should handle another simple where", () => { // [START simple_queries_again] - var citiesRef = db.collection("cities"); + const { collection, query, where } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); - var query = citiesRef.where("capital", "==", true); + const q = query(citiesRef, where("capital", "==", true)); // [END simple_queries_again] }); it("should handle other wheres", () => { - var citiesRef = db.collection("cities"); - // [START example_filters] - citiesRef.where("state", "==", "CA") - citiesRef.where("population", "<", 100000) - citiesRef.where("name", ">=", "San Francisco") - // [END example_filters] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START example_filters] + citiesRef.where("state", "==", "CA") + citiesRef.where("population", "<", 100000) + citiesRef.where("name", ">=", "San Francisco") + // [END example_filters] }); it("should handle array-contains where", () => { - var citiesRef = db.collection("cities"); - // [START array_contains_filter] - citiesRef.where("regions", "array-contains", "west_coast") - // [END array_contains_filter] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START array_contains_filter] + const { query, where } = require("@firebase/firestore"); + const q = query(citiesRef, where("regions", "array-contains", "west_coast")); + // [END array_contains_filter] }); it("should handle an array contains any where", () => { - const citiesRef = db.collection('cities'); - // [START array_contains_any_filter] - citiesRef.where('regions', 'array-contains-any', - ['west_coast', 'east_coast']); - // [END array_contains_any_filter] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START array_contains_any_filter] + const { query, where } = require("@firebase/firestore"); + + const q = query(citiesRef, + where('regions', 'array-contains-any', ['west_coast', 'east_coast'])); + // [END array_contains_any_filter] }); it("should handle an in where", () => { - const citiesRef = db.collection('cities'); + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + function inFilter() { // [START in_filter] - citiesRef.where('country', 'in', ['USA', 'Japan']); + const { query, where } = require("@firebase/firestore"); + + const q = query(citiesRef, where('country', 'in', ['USA', 'Japan'])); // [END in_filter] + } + function inFilterWithArray() { // [START in_filter_with_array] - citiesRef.where('regions', 'in', - [['west_coast', 'east_coast']]); + const { query, where } = require("@firebase/firestore"); + + const q = query(citiesRef, where('regions', 'in', [['west_coast', 'east_coast']])); // [END in_filter_with_array] + } }); it("should handle compound queries", () => { - var citiesRef = db.collection("cities"); - // [START chain_filters] - citiesRef.where("state", "==", "CO").where("name", "==", "Denver"); - citiesRef.where("state", "==", "CA").where("population", "<", 1000000); - // [END chain_filters] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START chain_filters] + const { query, where } = require("@firebase/firestore"); + + const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); + const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000)); + // [END chain_filters] }); it("should handle range filters on one field", () => { - var citiesRef = db.collection("cities"); - // [START valid_range_filters] - citiesRef.where("state", ">=", "CA").where("state", "<=", "IN"); - citiesRef.where("state", "==", "CA").where("population", ">", 1000000); - // [END valid_range_filters] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START valid_range_filters] + const { query, where } = require("@firebase/firestore"); + + const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); + const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000)); + // [END valid_range_filters] }); it("should not handle range filters on multiple field", () => { - var citiesRef = db.collection("cities"); - expect(() => { - // [START invalid_range_filters] - citiesRef.where("state", ">=", "CA").where("population", ">", 100000); - // [END invalid_range_filters] - }).to.throwException(); + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + expect(() => { + // [START invalid_range_filters] + const { query, where } = require("@firebase/firestore"); + + const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000)); + // [END invalid_range_filters] + }).to.throwException(); }); it("should order and limit", () => { - var citiesRef = db.collection("cities"); - // [START order_and_limit] - citiesRef.orderBy("name").limit(3) - // [END order_and_limit] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_limit] + const { query, orderBy, limit } = require("@firebase/firestore"); + + const q = query(citiesRef, orderBy("name"), limit(3)); + // [END order_and_limit] }); it("should order descending", () => { - var citiesRef = db.collection("cities"); - // [START order_and_limit_desc] - citiesRef.orderBy("name", "desc").limit(3) - // [END order_and_limit_desc] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_limit_desc] + const { query, orderBy, limit } = require("@firebase/firestore"); + + const q = query(citiesRef, orderBy("name", "desc"), limit(3)); + // [END order_and_limit_desc] }); it("should order descending by other field", () => { - var citiesRef = db.collection("cities"); - // [START order_multiple] - citiesRef.orderBy("state").orderBy("population", "desc") - // [END order_multiple] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_multiple] + const { query, orderBy } = require("@firebase/firestore"); + + const q = query(citiesRef, orderBy("state"), orderBy("population", "desc")); + // [END order_multiple] }); it("should where and order by with limit", () => { - var citiesRef = db.collection("cities"); - // [START filter_and_order] - citiesRef.where("population", ">", 100000).orderBy("population").limit(2) - // [END filter_and_order] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START filter_and_order] + const { query, where, orderBy, limit } = require("@firebase/firestore"); + + const q = query(citiesRef, where("population", ">", 100000), orderBy("population"), limit(2)); + // [END filter_and_order] }); it("should where and order on same field", () => { - var citiesRef = db.collection("cities"); - // [START valid_filter_and_order] - citiesRef.where("population", ">", 100000).orderBy("population") - // [END valid_filter_and_order] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START valid_filter_and_order] + const { query, where, orderBy } = require("@firebase/firestore"); + + const q = query(citiesRef, where("population", ">", 100000), orderBy("population")); + // [END valid_filter_and_order] }); it("should not where and order on same field", () => { - var citiesRef = db.collection("cities"); - expect(() => { - // [START invalid_filter_and_order] - citiesRef.where("population", ">", 100000).orderBy("country") - // [END invalid_filter_and_order] - }).to.throwException(); + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + expect(() => { + // [START invalid_filter_and_order] + const { query, where, orderBy } = require("@firebase/firestore"); + + const q = query(citiesRef, where("population", ">", 100000), orderBy("country")); + // [END invalid_filter_and_order] + }).to.throwException(); }); it("should handle startAt", () => { - var citiesRef = db.collection("cities"); - // [START order_and_start] - citiesRef.orderBy("population").startAt(1000000) - // [END order_and_start] + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_start] + const { query, orderBy, startAt } = require("@firebase/firestore"); + + const q = query(citiesRef, orderBy("population"), startAt(1000000)); + // [END order_and_start] }); it("should handle endAt", () => { - var citiesRef = db.collection("cities"); - // [START order_and_end] - citiesRef.orderBy("population").endAt(1000000) - // [END order_and_end] - }); + const { collection } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); - it("should handle startAt(doc) ", () => { - // [START start_doc] - var citiesRef = db.collection("cities"); + // [START order_and_end] + const { query, orderBy, endAt } = require("@firebase/firestore"); - return citiesRef.doc("SF").get().then(function(doc) { - // Get all cities with a population bigger than San Francisco - var biggerThanSf = citiesRef - .orderBy("population") - .startAt(doc); + const q = query(citiesRef, orderBy("population"), endAt(1000000)); + // [END order_and_end] + }); - // ... - }); - // [END start_doc] + it("should handle startAt(doc) ", async () => { + // [START start_doc] + const { collection, doc, getDoc, query, orderBy, startAt } = require("@firebase/firestore"); + const citiesRef = collection(db, "cities"); + + const docSnap = await getDoc(doc(citiesRef, "SF")); + + // Get all cities with a population bigger than San Francisco + const biggerThanSf = query(citiesRef, orderBy("popuation"), startAt(docSnap)); + // ... + // [END start_doc] }); it("should handle multiple orderBy", () => { // [START start_multiple_orderby] // Will return all Springfields - db.collection("cities") - .orderBy("name") - .orderBy("state") - .startAt("Springfield") + const { collection, query, orderBy, startAt } = require("@firebase/firestore"); + const q1 = query(collection(db, "cities"), + orderBy("name"), + orderBy("state"), + startAt("Springfield")); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" - db.collection("cities") - .orderBy("name") - .orderBy("state") - .startAt("Springfield", "Missouri") + const q2 = query(collection(db, "cities"), + orderBy("name"), + orderBy("state"), + startAt("Springfield", "Missouri")); // [END start_multiple_orderby] }); - it("shoud paginate", () => { + it("should paginate", async () => { // [START paginate] - var first = db.collection("cities") - .orderBy("population") - .limit(25); - - return first.get().then(function (documentSnapshots) { - // Get the last visible document - var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; - console.log("last", lastVisible); - - // Construct a new query starting at this document, - // get the next 25 cities. - var next = db.collection("cities") - .orderBy("population") - .startAfter(lastVisible) - .limit(25); - }); + const { collection, query, orderBy, startAfter, limit, getDocs } = require("@firebase/firestore"); + + // Query the first page of docs + const first = query(collection(db, "cities"), orderBy("population"), limit(25)); + const documentSnapshots = await getDocs(first); + + // Get the last visible document + const lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; + console.log("last", lastVisible); + + // Construct a new query starting at this document, + // get the next 25 cities. + const next = query(collection(db, "cities"), + orderBy("population"), + startAfter(lastVisible), + limit(25)); // [END paginate] }); }); - describe('collectionGroup(landmarks', () => { - it("should setup example data", () => { + describe('collectionGroup(landmarks)', () => { + it("should setup example data", async () => { // [START fs_collection_group_query_data_setup] - var citiesRef = db.collection('cities'); + const { collection, doc, setDoc } = require("@firebase/firestore"); + + const citiesRef = collection(db, 'cities'); - var landmarks = Promise.all([ - citiesRef.doc('SF').collection('landmarks').doc().set({ + await Promise.all([ + setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { name: 'Golden Gate Bridge', type: 'bridge' }), - citiesRef.doc('SF').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { name: 'Legion of Honor', type: 'museum' }), - citiesRef.doc('LA').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { name: 'Griffith Park', type: 'park' }), - citiesRef.doc('LA').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { name: 'The Getty', type: 'museum' }), - citiesRef.doc('DC').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { name: 'Lincoln Memorial', type: 'memorial' }), - citiesRef.doc('DC').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { name: 'National Air and Space Museum', type: 'museum' }), - citiesRef.doc('TOK').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { name: 'Ueno Park', type: 'park' }), - citiesRef.doc('TOK').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { name: 'National Museum of Nature and Science', type: 'museum' }), - citiesRef.doc('BJ').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { name: 'Jingshan Park', type: 'park' }), - citiesRef.doc('BJ').collection('landmarks').doc().set({ + setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { name: 'Beijing Ancient Observatory', type: 'museum' }) ]); // [END fs_collection_group_query_data_setup] - return landmarks; }); - it("should query a collection group", () => { + it("should query a collection group", async () => { // [START fs_collection_group_query] - var museums = db.collectionGroup('landmarks').where('type', '==', 'museum'); - museums.get().then(function (querySnapshot) { - querySnapshot.forEach(function (doc) { - console.log(doc.id, ' => ', doc.data()); - }); + const { collectionGroup, query, where, getDocs } = require("@firebase/firestore"); + + const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum')); + const querySnapshot = await getDocs(museums); + querySnapshot.forEach((doc) => { + console.log(doc.id, ' => ', doc.data()); }); // [END fs_collection_group_query] }); @@ -1069,46 +1133,47 @@ describe("firestore", () => { // TODO: Break out into separate file describe("solution-aggregation", () => { - it("should update a restaurant in a transaction #UNVERIFIED", () => { + it("should update a restaurant in a transaction #UNVERIFIED", async () => { // [START add_rating_transaction] - function addRating(restaurantRef, rating) { + const { collection, doc, runTransaction} = require("@firebase/firestore"); + + async function addRating(restaurantRef, rating) { // Create a reference for a new rating, for use inside the transaction - var ratingRef = restaurantRef.collection('ratings').doc(); + const ratingRef = doc(collection(restaurantRef, 'ratings')); // In a transaction, add the new rating and update the aggregate totals - return db.runTransaction(transaction => { - return transaction.get(restaurantRef).then(res => { - if (!res.exists) { - throw "Document does not exist!"; - } + await runTransaction(db, async (transaction) => { + const res = await transaction.get(restaurantRef); + if (!res.exists()) { + throw "Document does not exist!"; + } - // Compute new number of ratings - var newNumRatings = res.data().numRatings + 1; + // Compute new number of ratings + const newNumRatings = res.data().numRatings + 1; - // Compute new average rating - var oldRatingTotal = res.data().avgRating * res.data().numRatings; - var newAvgRating = (oldRatingTotal + rating) / newNumRatings; + // Compute new average rating + const oldRatingTotal = res.data().avgRating * res.data().numRatings; + const newAvgRating = (oldRatingTotal + rating) / newNumRatings; - // Commit to Firestore - transaction.update(restaurantRef, { - numRatings: newNumRatings, - avgRating: newAvgRating - }); - transaction.set(ratingRef, { rating: rating }); - }) + // Commit to Firestore + transaction.update(restaurantRef, { + numRatings: newNumRatings, + avgRating: newAvgRating + }); + transaction.set(ratingRef, { rating: rating }); }); } // [END add_rating_transaction] // Create document and add a rating - var ref = db.collection('restaurants').doc('arinell-pizza'); - return ref.set({ + const { setDoc } = require("@firebase/firestore"); + const ref = doc(collection(db, 'restaurants'), ('arinell-pizza')); + await setDoc(ref, { name: 'Arinell Pizza', avgRating: 4.63, numRatings: 683 - }).then(res => { - return addRating(ref, 5.0) }); + await addRating(ref, 5.0); }); }); }); From e26834e539e1dbdd18a5e8f3d7dc2c8db80236e4 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Sep 2020 12:12:44 +0100 Subject: [PATCH 06/22] Solution aggregation --- firestore/test.solution-aggregation.js | 37 +++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/firestore/test.solution-aggregation.js b/firestore/test.solution-aggregation.js index 024a3a58..f7b6bd25 100644 --- a/firestore/test.solution-aggregation.js +++ b/firestore/test.solution-aggregation.js @@ -1,5 +1,5 @@ // [START sample_doc] -var arinellDoc = { +const arinellDoc = { name: 'Arinell Pizza', avgRating: 4.65, numRatings: 683 @@ -7,28 +7,29 @@ var arinellDoc = { // [END sample_doc] describe("firestore-solution-arrays", () => { - var db; - before(() => { - var config = { - apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", - authDomain: "firestorequickstarts.firebaseapp.com", - projectId: "firestorequickstarts", - }; - var app = firebase.initializeApp(config, "solution-arrays"); - db = firebase.firestore(app); + let db; + before(async () => { + const { initializeApp } = require("@firebase/app"); + const { getFirestore, collection, doc, setDoc } = require("@firebase/firestore"); - return db.collection("restaurants") - .doc("arinell-pizza") - .set(arinellDoc); + const config = { + apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", + authDomain: "firestorequickstarts.firebaseapp.com", + projectId: "firestorequickstarts", + }; + const app = initializeApp(config, "solution-arrays"); + db = getFirestore(app); + + await setDoc(doc(collection(db, "restaurants"), "arinell-pizza"), arinellDoc); }); describe("solution-arrays", () => { - it("should get a collection of ratings", () => { + it("should get a collection of ratings", async () => { // [START get_collection_ratings] - db.collection("restaurants") - .doc("arinell-pizza") - .collection("ratings") - .get() + const { collection, doc, getDocs } = require("@firebase/firestore"); + + const ratingsRef = collection(doc(collection(db, "restaurants"), "arinell-pizza"), "ratings"); + const ratingsDocs = await getDocs(ratingsRef); // [END get_collection_ratings] }) }); From 1bb37fa92e8b126e0759ad9e35cfa6edb095e381 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Sep 2020 12:16:38 +0100 Subject: [PATCH 07/22] Solutiona arrays --- firestore/test.solution-arrays.js | 62 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/firestore/test.solution-arrays.js b/firestore/test.solution-arrays.js index d233b0c6..4004de9f 100644 --- a/firestore/test.solution-arrays.js +++ b/firestore/test.solution-arrays.js @@ -1,4 +1,4 @@ -let postsWithArray = [ +const postsWithArray = [ // [START post_with_array] // Sample document in the 'posts' collection. { @@ -12,7 +12,7 @@ let postsWithArray = [ // [END post_with_array] ]; -let postsWithMap = [ +const postsWithMap = [ // [START post_with_map] // Sample document in the 'posts' collection { @@ -26,7 +26,7 @@ let postsWithMap = [ // [END post_with_map] ]; -let postsWithMapAdvanced = [ +const postsWithMapAdvanced = [ // [START post_with_map_advanced] // The value of each entry in 'categories' is a unix timestamp { @@ -41,43 +41,55 @@ let postsWithMapAdvanced = [ ] describe("firestore-solution-arrays", () => { - var db; + let db; before(() => { - var config = { + const { initializeApp } = require("@firebase/app"); + const { getFirestore } = require("@firebase/firestore"); + + const config = { apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", authDomain: "firestorequickstarts.firebaseapp.com", projectId: "firestorequickstarts", }; - var app = firebase.initializeApp(config, "solution-arrays"); - db = firebase.firestore(app); + const app = initializeApp(config, "solution-arrays"); + db = getFirestore(app); }); describe("solution-arrays", () => { - it("should query in a category #UNVERIFIED", () => { + it("should query in a category", async () => { // [START query_in_category] + const { collection, getDocs, query, where } = require("@firebase/firestore"); + // Find all documents in the 'posts' collection that are // in the 'cats' category. - db.collection('posts') - .where('categories.cats', '==', true) - .get() - .then(() => { - // ... - }); + const q = query(collection(db, "posts"), where("categories.cats", "==", true)); + const docs = await getDocs(q); + // ... // [END query_in_category] }); - it("should query in a category by timestamp #UNVERIFIED", () => { - // [START query_in_category_timestamp_invalid] - db.collection('posts') - .where('categories.cats', '==', true) - .orderBy('timestamp'); - // [END query_in_category_timestamp_invalid] + it("should query in a category by timestamp", () => { + function queryOne() { + // [START query_in_category_timestamp_invalid] + const { collection, query, where, orderBy } = require("@firebase/firestore"); + + const q = query(collection(db, "posts"), + where("categories.cats", "==", true), + orderBy("timestamp")); + // [END query_in_category_timestamp_invalid] + } + + + function queryTwo() { + // [START query_in_category_timestamp] + const { collection, query, where, orderBy } = require("@firebase/firestore"); + + const q = query(collection(db, "posts"), + where("categories.cats", ">", 0), + orderBy("categories.cats")); + // [END query_in_category_timestamp] + } - // [START query_in_category_timestamp] - db.collection('posts') - .where('categories.cats', '>', 0) - .orderBy('categories.cats'); - // [END query_in_category_timestamp] }); }); }); From 9beafb7a2dc57a7d4bc5b5ebddfad6aa44ccda20 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Sep 2020 12:22:24 +0100 Subject: [PATCH 08/22] Solution counters --- firestore/test.solution-counters.js | 70 +++++++++++++++++------------ 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/firestore/test.solution-counters.js b/firestore/test.solution-counters.js index e831807e..c4053704 100644 --- a/firestore/test.solution-counters.js +++ b/firestore/test.solution-counters.js @@ -1,15 +1,17 @@ -var db; +let db; // [START create_counter] function createCounter(ref, num_shards) { - var batch = db.batch(); + const { collection, doc, writeBatch} = require("@firebase/firestore"); + + const batch = writeBatch(db); // Initialize the counter document batch.set(ref, { num_shards: num_shards }); // Initialize each shard with count=0 for (let i = 0; i < num_shards; i++) { - let shardRef = ref.collection('shards').doc(i.toString()); + const shardRef = doc(collection(ref, 'shards'), i.toString()); batch.set(shardRef, { count: 0 }); } @@ -20,62 +22,72 @@ function createCounter(ref, num_shards) { // [START increment_counter] function incrementCounter(db, ref, num_shards) { + const { collection, doc, updateDoc, increment } = require("@firebase/firestore"); + // Select a shard of the counter at random - const shard_id = Math.floor(Math.random() * num_shards).toString(); - const shard_ref = ref.collection('shards').doc(shard_id); + const shardId = Math.floor(Math.random() * num_shards).toString(); + const shardRef = doc(collection(ref, 'shards'), shardId); // Update count - return shard_ref.update("count", firebase.firestore.FieldValue.increment(1)); + return updateDoc(shardRef, "count", increment(1)); } // [END increment_counter] // [START get_count] -function getCount(ref) { +async function getCount(ref) { + const { collection, getDocs } = require("@firebase/firestore"); + // Sum the count of each shard in the subcollection - return ref.collection('shards').get().then(snapshot => { - let total_count = 0; - snapshot.forEach(doc => { - total_count += doc.data().count; - }); + const snapshot = await getDocs(collection(ref, 'shards')); - return total_count; + let totalCount = 0; + snapshot.forEach(doc => { + totalCount += doc.data().count; }); + + return totalCount; } // [END get_count] describe("firestore-solution-counters", () => { before(() => { - var config = { + const { initializeApp } = require("@firebase/app"); + const { getFirestore } = require("@firebase/firestore"); + + const config = { apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", authDomain: "firestorequickstarts.firebaseapp.com", projectId: "firestorequickstarts", }; - var app = firebase.initializeApp(config, "solution-counters"); - db = firebase.firestore(app); + const app = initializeApp(config, "solution-arrays"); + db = getFirestore(app); }); describe("solution-counters", () => { it("should create a counter", () => { // Create a counter with 10 shards - return createCounter(db.collection('counters').doc(), 10); + const { collection, doc } = require("@firebase/firestore"); + + return createCounter(doc(collection(db, 'counters')), 10); }); - it("should increment a counter", () => { + it("should increment a counter", async () => { // Create a counter, then increment it - let ref = db.collection('counters').doc(); - return createCounter(ref, 10).then(() => { - return incrementCounter(db, ref, 10); - }); + const { collection, doc } = require("@firebase/firestore"); + + const ref = doc(collection(db, 'counters')); + await createCounter(ref, 10) + await incrementCounter(db, ref, 10); }); - it("should get the count of a counter", () => { + it("should get the count of a counter", async () => { // Create a counter, increment it, then get the count - let ref = db.collection('counters').doc(); - return createCounter(ref, 10).then(() => { - return incrementCounter(db, ref, 10); - }).then(() => { - return getCount(ref); - }); + const { collection, doc } = require("@firebase/firestore"); + + const ref = doc(collection(db, 'counters')); + await createCounter(ref, 10); + await incrementCounter(db, ref, 10); + await getCount(ref); }); }); }); From 9ecee2e5c03506e844b9e78afc44c69789b73c24 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 3 Sep 2020 11:23:17 +0100 Subject: [PATCH 09/22] Firestore compiles --- firestore/emulator-suite.js | 12 +++++---- firestore/test.firestore.js | 52 ++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/firestore/emulator-suite.js b/firestore/emulator-suite.js index e7b911ef..65f6a400 100644 --- a/firestore/emulator-suite.js +++ b/firestore/emulator-suite.js @@ -1,14 +1,16 @@ -import { getFirestore } from "@firebase/firestore"; +const { initializeFirestore } = require("firebase/firestore"); function onDocumentReady(firebaseApp) { //[START fs_emulator_connect] - // Firebase previously initialized using firebase.initializeApp(). - const db = getFirestore(firebaseApp); + let settings = {}; if (location.hostname === "localhost") { - db.settings({ + settings = { host: "localhost:8080", ssl: false - }); + }; } + + // firebaseApps previously initialized using initializeApp() + const db = initializeFirestore(firebaseApp, settings); // [END fs_emulator_connect] } diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index 0c3a6cd8..a080a08f 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -106,8 +106,8 @@ describe("firestore", () => { // [START use_from_cache] const { collection, onSnapshot, where, query } = require("firebase/firestore"); - const query = query(collection(db, "cities"), where("state", "==", "CA")); - onSnapshot(query, { includeMetadataChanges: true }, (snapshot) => { + const q = query(collection(db, "cities"), where("state", "==", "CA")); + onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => { snapshot.docChanges().forEach((change) => { if (change.type === "added") { console.log("New city: ", change.doc.data()); @@ -216,7 +216,7 @@ describe("firestore", () => { // [START subcollection_reference] const { doc, collection } = require("firebase/firestore"); - const messageRef = doc(collection(doc(collection("rooms"), "roomA"), "messages"), "message1"); + const messageRef = doc(collection(doc(collection(db, "rooms"), "roomA"), "messages"), "message1"); // [END subcollection_reference] }); @@ -247,11 +247,11 @@ describe("firestore", () => { // [START get_custom_object] const { doc, collection, getDoc} = require("firebase/firestore"); - const ref = collection(doc(db, "cities"), "LA").withConverter(cityConverter); - const doc = await getDoc(ref); - if (doc.exists) { + const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); + const docSnap = await getDoc(ref); + if (docSnap.exists()) { // Convert to City object - city = doc.data(); + const city = docSnap.data(); // Use a City instance method console.log(city.toString()); } else { @@ -313,7 +313,6 @@ describe("firestore", () => { const cityRef = doc(collection(db, 'cities'), 'BJ'); setDoc(cityRef, { capital: true }, { merge: true }); // [END set_with_merge] - return setWithMerge; }); it("should update a document's nested fields #UNVERIFIED", async () => { @@ -420,7 +419,7 @@ describe("firestore", () => { // [START cities_document_set] const { collection, doc, setDoc } = require("firebase/firestore"); - await setDoc(doc(collection("cities"), "new-city-id"), data); + await setDoc(doc(collection(db, "cities"), "new-city-id"), data); // [END cities_document_set] }); @@ -435,7 +434,6 @@ describe("firestore", () => { }); console.log("Document written with ID: ", docRef.id); // [END add_document] - return output; }); it("should add an empty a document", async () => { @@ -469,7 +467,7 @@ describe("firestore", () => { // [START update_document_array] const { collection, doc, updateDoc, arrayUnion, arrayRemove } = require("firebase/firestore"); - const washingtonRef = doc(collection("db", cities), "DC"); + const washingtonRef = doc(collection(db, "cities"), "DC"); // Atomically add a new region to the "regions" array field. await updateDoc(washingtonRef, { @@ -487,7 +485,7 @@ describe("firestore", () => { // [START update_document_increment] const { collection, doc, updateDoc, increment } = require("firebase/firestore"); - const washingtonRef = doc(collection("db", cities), "DC"); + const washingtonRef = doc(collection(db, "cities"), "DC"); // Atomically increment the population of the city by 50. await updateDoc(washingtonRef, { @@ -502,7 +500,6 @@ describe("firestore", () => { await deleteDoc(doc(collection(db, "cities"), "DC")); // [END delete_document] - return output; }); it("should handle transactions", async () => { @@ -539,7 +536,7 @@ describe("firestore", () => { const sfDocRef = doc(collection(db, "cities"), "SF"); try { - const newPopulation = await runTransaction(db, (transaction) => { + const newPopulation = await runTransaction(db, async (transaction) => { const sfDoc = await transaction.get(sfDocRef); if (!sfDoc.exists()) { throw "Document does not exist!"; @@ -566,10 +563,10 @@ describe("firestore", () => { const { collection, doc, getDoc } = require("firebase/firestore"); const docRef = doc(collection(db, "cities"), "SF"); - const doc = await getDoc(docRef); + const docSnap = await getDoc(docRef); - if (doc.exists) { - console.log("Document data:", doc.data()); + if (docSnap.exists()) { + console.log("Document data:", docSnap.data()); } else { // doc.data() will be undefined in this case console.log("No such document!"); @@ -657,7 +654,6 @@ describe("firestore", () => { console.log(doc.id, " => ", doc.data()); }); // [END get_multiple] - return output; }).timeout(5000); it("should get all documents from a collection", async () => { @@ -670,8 +666,7 @@ describe("firestore", () => { console.log(doc.id, " => ", doc.data()); }); // [END get_multiple_all] - return output; - }) + }); it("should listen on multiple documents #UNVERIFIED", (done) => { // [START listen_multiple] @@ -774,7 +769,7 @@ describe("firestore", () => { it("should use options to control server timestamp resolution", async () => { // [START server_timestamp_resolution_options] - const { collection, updateDoc, serverTimestamp, onSnapshot } = require("firebase/firestore"); + const { collection, doc, updateDoc, serverTimestamp, onSnapshot } = require("firebase/firestore"); // Perform an update followed by an immediate read without // waiting for the update to complete. Due to the snapshot // options we will get two results: one with an estimate @@ -785,11 +780,10 @@ describe("firestore", () => { }); onSnapshot(docRef, (snapshot) => { - const options = { + const data = snapshot.data({ // Options: 'estimate', 'previous', or 'none' - serverTimestamps: 'estimate' - }; - const data = snapshot.data(options); + serverTimestamps: "estimate" + }); console.log( 'Timestamp: ' + data.timestamp + ', pending: ' + snapshot.metadata.hasPendingWrites); @@ -839,13 +833,13 @@ describe("firestore", () => { }); it("should handle other wheres", () => { - const { collection } = require("firebase/firestore"); + const { collection, query, where } = require("firebase/firestore"); const citiesRef = collection(db, "cities"); // [START example_filters] - citiesRef.where("state", "==", "CA") - citiesRef.where("population", "<", 100000) - citiesRef.where("name", ">=", "San Francisco") + const q1 = query(citiesRef, where("state", "==", "CA")); + const q2 = query(citiesRef, where("population", "<", 100000)); + const q3 = query(citiesRef, where("name", ">=", "San Francisco")); // [END example_filters] }); From 4eae121a2c436f7f5910c7bd1fd4acea4016ea5f Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 3 Sep 2020 15:58:20 +0100 Subject: [PATCH 10/22] Increase typing --- firestore/emulator-suite.js | 4 ++-- firestore/test.firestore.js | 25 ++++++++++++++++++------- firestore/test.solution-aggregation.js | 4 ++++ firestore/test.solution-arrays.js | 8 ++++++-- firestore/test.solution-counters.js | 5 ++++- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/firestore/emulator-suite.js b/firestore/emulator-suite.js index 65f6a400..a476c2c8 100644 --- a/firestore/emulator-suite.js +++ b/firestore/emulator-suite.js @@ -1,7 +1,7 @@ -const { initializeFirestore } = require("firebase/firestore"); - function onDocumentReady(firebaseApp) { //[START fs_emulator_connect] + const { initializeFirestore } = require("firebase/firestore"); + let settings = {}; if (location.hostname === "localhost") { settings = { diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index a080a08f..db0a56f1 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -1,5 +1,3 @@ -const { initializeApp } = require("firebase/app"); -const { getFirestore, CACHE_SIZE_UNLIMITED } = require("firebase/firestore"); const { expect } = require('chai'); // [START city_custom_object] @@ -31,26 +29,39 @@ var cityConverter = { // [END city_custom_object] describe("firestore", () => { + const { FirebaseFirestore } = require("firebase/firestore"); + + /** @type {FirebaseFirestore} */ let db; + let app; + before(() => { + const { initializeApp } = require("firebase/app"); + const { getFirestore } = require("firebase/firestore"); + const config = { apiKey: "AIzaSyCM61mMr_iZnP1DzjT1PMB5vDGxfyWNM64", authDomain: "firestore-snippets.firebaseapp.com", projectId: "firestore-snippets" }; - const app = initializeApp(config); + app = initializeApp(config); db = getFirestore(app); }); it("should be able to set the cache size", () => { // [START fs_setup_cache] - db.settings({ - cacheSizeBytes: CACHE_SIZE_UNLIMITED + const { initializeFirestore, CACHE_SIZE_UNLIMITED } = require("firebase/firestore"); + + const firestoreDb = initializeFirestore(app, { + cacheSizeBytes: CACHE_SIZE_UNLIMITED }); // [END fs_setup_cache] }); it("should be initializable with persistence", () => { + const { initializeApp } = require("firebase/app"); + const { getFirestore } = require("firebase/firestore"); + const app = initializeApp({ apiKey: '### FIREBASE API KEY ###', authDomain: '### FIREBASE AUTH DOMAIN ###', @@ -140,9 +151,9 @@ describe("firestore", () => { it("should get all users", async () => { // [START get_all_users] - const { getDocs } = require("firebase/firestore"); + const { collection, getDocs } = require("firebase/firestore"); - const querySnapshot = await getDocs(db.collection("users")); + const querySnapshot = await getDocs(collection(db, "users")); querySnapshot.forEach((doc) => { console.log(`${doc.id} => ${doc.data()}`); }); diff --git a/firestore/test.solution-aggregation.js b/firestore/test.solution-aggregation.js index 81007fc9..4c7a98a1 100644 --- a/firestore/test.solution-aggregation.js +++ b/firestore/test.solution-aggregation.js @@ -7,7 +7,11 @@ const arinellDoc = { // [END sample_doc] describe("firestore-solution-arrays", () => { + const { FirebaseFirestore } = require("firebase/firestore"); + + /** @type {FirebaseFirestore} */ let db; + before(async () => { const { initializeApp } = require("firebase/app"); const { getFirestore, collection, doc, setDoc } = require("firebase/firestore"); diff --git a/firestore/test.solution-arrays.js b/firestore/test.solution-arrays.js index 0a608386..0c4c6c60 100644 --- a/firestore/test.solution-arrays.js +++ b/firestore/test.solution-arrays.js @@ -41,11 +41,15 @@ const postsWithMapAdvanced = [ ] describe("firestore-solution-arrays", () => { + const { FirebaseFirestore } = require("firebase/firestore"); + + /** @type {FirebaseFirestore} */ let db; + before(() => { const { initializeApp } = require("firebase/app"); const { getFirestore } = require("firebase/firestore"); - + const config = { apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", authDomain: "firestorequickstarts.firebaseapp.com", @@ -71,7 +75,7 @@ describe("firestore-solution-arrays", () => { it("should query in a category by timestamp", () => { function queryOne() { // [START query_in_category_timestamp_invalid] - const { collection, query, where, orderBy } = require("@firebase/firestore"); + const { collection, query, where, orderBy, FirebaseFirestore } = require("@firebase/firestore"); const q = query(collection(db, "posts"), where("categories.cats", "==", true), diff --git a/firestore/test.solution-counters.js b/firestore/test.solution-counters.js index 853ed72d..7ca9c86f 100644 --- a/firestore/test.solution-counters.js +++ b/firestore/test.solution-counters.js @@ -1,3 +1,6 @@ +const { FirebaseFirestore } = require('firebase/firestore'); + +/** @type {FirebaseFirestore} */ let db; // [START create_counter] @@ -22,7 +25,7 @@ function createCounter(ref, num_shards) { // [START increment_counter] function incrementCounter(db, ref, num_shards) { - const { collection, doc, updateDoc, increment } = require("@firebase/firestore"); + const { collection, doc, updateDoc, increment, FirebaseFirestore } = require("@firebase/firestore"); // Select a shard of the counter at random const shardId = Math.floor(Math.random() * num_shards).toString(); From e618590bb85d583b4fbe9686f015eadf736b01b4 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 3 Sep 2020 17:40:18 +0100 Subject: [PATCH 11/22] Make a script to separate snippets --- scripts/package.json | 9 +++ scripts/separate-snippets.ts | 137 +++++++++++++++++++++++++++++++++++ snippets/README.md | 3 + 3 files changed, 149 insertions(+) create mode 100644 scripts/package.json create mode 100644 scripts/separate-snippets.ts create mode 100644 snippets/README.md diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 00000000..72b9bf11 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,9 @@ +{ + "name": "scripts", + "version": "1.0.0", + "description": "Internal repo scripts", + "scripts": { + }, + "author": "samstern@google.com", + "license": "Apache-2.0" +} diff --git a/scripts/separate-snippets.ts b/scripts/separate-snippets.ts new file mode 100644 index 00000000..562de0fc --- /dev/null +++ b/scripts/separate-snippets.ts @@ -0,0 +1,137 @@ +import * as cp from "child_process"; +import * as fs from "fs"; +import * as path from "path"; + +const RE_START_SNIPPET = /\[START\s+([A-Za-z_]+)\s*\]/; +const RE_END_SNIPPET = /\[END\s+([A-Za-z_]+)\s*\]/; +// TODO: Handle multiline imports? +const RE_REQUIRE = /const {(.+?)} = require\((.+?)\)/; + +function isBlank(line: string) { + return line.trim().length === 0; +} + +/** + * Turns a series of source lines into a standalone snippet file by: + * - Converting require statements into top-level imports. + * - Adjusting indentation to left-align all content + * - Removing any blank lines at the starts + * @param lines the lines containing the snippet (including START/END comments) + */ +function processSnippet(lines: string[]): string { + const importLines: string[] = []; + const otherLines: string[] = []; + + for (const line of lines) { + const requireMatch = line.match(RE_REQUIRE); + if (requireMatch) { + const asImport = `import {${requireMatch[1]}} from ${requireMatch[2]}`; + importLines.push(asImport); + } else { + otherLines.push(line); + } + } + + // Adjust indentation of the otherLines so that they're left aligned + const nonBlankLines = otherLines.filter((l) => !isBlank(l)); + const indentSizes = nonBlankLines.map((l) => l.length - l.trimLeft().length); + const minIndent = Math.min(...indentSizes); + + const adjustedOtherLines: string[] = []; + for (const line of otherLines) { + if (isBlank(line)) { + adjustedOtherLines.push(""); + } else { + adjustedOtherLines.push(line.substr(minIndent)); + } + } + + // Special case: if the first line after the comments is blank we want to remove it + const firstNonComment = adjustedOtherLines.findIndex( + (l) => !l.startsWith("//") + ); + if (isBlank(otherLines[firstNonComment])) { + adjustedOtherLines.splice(firstNonComment, 1); + } + + // TODO: Should we add a preamble? + const content = [...importLines, ...adjustedOtherLines].join("\n"); + return content; +} + +/** + * Lists all the files in this repository that should be checked for snippets + */ +function listSnippetFiles(): string[] { + const output = cp + .execSync( + 'find . -type f -name "*.js" -not -path "*node_modules*" -not -path "./snippets*"' + ) + .toString(); + return output.split("\n").filter((x) => !isBlank(x)); +} + +/** + * Collect all the snippets from a file into a map of snippet name to lines. + * @param filePath the file path to read. + */ +function collectSnippets(filePath: string): { [name: string]: string[] } { + const fileContents = fs.readFileSync(filePath).toString(); + const lines = fileContents.split("\n"); + + let currSnippetName = ""; + let inSnippet = false; + const snippetLines: { [name: string]: string[] } = {}; + for (const line of lines) { + const startMatch = line.match(RE_START_SNIPPET); + const endMatch = line.match(RE_END_SNIPPET); + + if (startMatch) { + inSnippet = true; + currSnippetName = startMatch[1]; + snippetLines[currSnippetName] = []; + } + + if (inSnippet) { + snippetLines[currSnippetName].push(line); + } + + if (endMatch) { + if (endMatch[1] !== currSnippetName) { + throw new Error( + `Snippet ${currSnippetName} in ${filePath} has unmatched START/END tags` + ); + } + inSnippet = false; + } + } + + return snippetLines; +} + +async function main() { + const fileNames = listSnippetFiles(); + + for (const filePath of fileNames) { + const fileSlug = filePath + .replace(".js", "") + .replace("./", "") + .replace(/\./g, "-"); + const snippetDir = path.join("./snippets", fileSlug); + + console.log(`Processing: ${filePath} --> ${snippetDir}`); + + if (!fs.existsSync(snippetDir)) { + fs.mkdirSync(snippetDir, { recursive: true }); + } + + const snippetLines = collectSnippets(filePath); + for (const snippetName in snippetLines) { + const filePath = path.join(snippetDir, `${snippetName}.js`); + const content = processSnippet(snippetLines[snippetName]); + fs.writeFileSync(filePath, content); + } + } +} + +main(); diff --git a/snippets/README.md b/snippets/README.md new file mode 100644 index 00000000..8dc6a751 --- /dev/null +++ b/snippets/README.md @@ -0,0 +1,3 @@ +# Ignore this folder + +This folder contains generated files based on the source in other folders! From 68bb5e4a26d8b9b4ff3d760780db2e8387f58e7d Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 13:03:08 +0100 Subject: [PATCH 12/22] Clean up separator script --- firestore/emulator-suite.js | 3 +- firestore/test.firestore.js | 1 + firestore/test.solution-aggregation.js | 1 + firestore/test.solution-arrays.js | 1 + firestore/test.solution-counters.js | 1 + package.json | 1 + scripts/separate-snippets.ts | 114 +++++++++++++++++++------ snippets/README.md | 27 +++++- 8 files changed, 119 insertions(+), 30 deletions(-) diff --git a/firestore/emulator-suite.js b/firestore/emulator-suite.js index a476c2c8..6e608dc7 100644 --- a/firestore/emulator-suite.js +++ b/firestore/emulator-suite.js @@ -1,5 +1,6 @@ +// [SNIPPETS_SEPARATION enabled] function onDocumentReady(firebaseApp) { - //[START fs_emulator_connect] + // [START fs_emulator_connect] const { initializeFirestore } = require("firebase/firestore"); let settings = {}; diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index db0a56f1..bcd5e7ef 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -1,3 +1,4 @@ +// [SNIPPETS_SEPARATION enabled] const { expect } = require('chai'); // [START city_custom_object] diff --git a/firestore/test.solution-aggregation.js b/firestore/test.solution-aggregation.js index 4c7a98a1..a2b8c487 100644 --- a/firestore/test.solution-aggregation.js +++ b/firestore/test.solution-aggregation.js @@ -1,3 +1,4 @@ +// [SNIPPETS_SEPARATION enabled] // [START sample_doc] const arinellDoc = { name: 'Arinell Pizza', diff --git a/firestore/test.solution-arrays.js b/firestore/test.solution-arrays.js index 0c4c6c60..7c2ee04d 100644 --- a/firestore/test.solution-arrays.js +++ b/firestore/test.solution-arrays.js @@ -1,3 +1,4 @@ +// [SNIPPETS_SEPARATION enabled] const postsWithArray = [ // [START post_with_array] // Sample document in the 'posts' collection. diff --git a/firestore/test.solution-counters.js b/firestore/test.solution-counters.js index 7ca9c86f..ab9eae36 100644 --- a/firestore/test.solution-counters.js +++ b/firestore/test.solution-counters.js @@ -1,3 +1,4 @@ +// [SNIPPETS_SEPARATION enabled] const { FirebaseFirestore } = require('firebase/firestore'); /** @type {FirebaseFirestore} */ diff --git a/package.json b/package.json index 9d3c88b5..6f1f8e21 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "snippets-web", "version": "1.0.0", "scripts": { + "snippets": "npx ts-node scripts/separate-snippets.ts", "lerna-bootstrap": "lerna bootstrap --no-ci", "lerna-compile": "lerna run compile" }, diff --git a/scripts/separate-snippets.ts b/scripts/separate-snippets.ts index 562de0fc..6b4c35a3 100644 --- a/scripts/separate-snippets.ts +++ b/scripts/separate-snippets.ts @@ -2,11 +2,28 @@ import * as cp from "child_process"; import * as fs from "fs"; import * as path from "path"; +// Regex for comment which must be included in a file for it to be separated +const RE_SNIPPETS_SEPARATION = /\[SNIPPETS_SEPARATION\s+enabled\]/; + +// Regex for comment to control the separator prefix +const RE_SNIPPETS_PREFIX = /\[SNIPPETS_PREFIX\s+([A-Za-z0-9_]+)\]/; + +// Regex for [START] and [END] snippet tags. const RE_START_SNIPPET = /\[START\s+([A-Za-z_]+)\s*\]/; const RE_END_SNIPPET = /\[END\s+([A-Za-z_]+)\s*\]/; + +// Regex for const = require statements // TODO: Handle multiline imports? const RE_REQUIRE = /const {(.+?)} = require\((.+?)\)/; +type SnippetsConfig = { + enabled: boolean; + prefix: string; + map: Record; +}; + +const DEFAULT_PREFIX = "modular_"; + function isBlank(line: string) { return line.trim().length === 0; } @@ -16,46 +33,63 @@ function isBlank(line: string) { * - Converting require statements into top-level imports. * - Adjusting indentation to left-align all content * - Removing any blank lines at the starts + * - Adding a prefix to snippet names + * * @param lines the lines containing the snippet (including START/END comments) + * @param sourceFile the source file where the original snippet lives + * @param snippetPrefix the prefix (such as modular_) */ -function processSnippet(lines: string[]): string { - const importLines: string[] = []; - const otherLines: string[] = []; +function processSnippet( + lines: string[], + sourceFile: string, + snippetPrefix: string +): string { + const outputLines: string[] = []; for (const line of lines) { - const requireMatch = line.match(RE_REQUIRE); - if (requireMatch) { - const asImport = `import {${requireMatch[1]}} from ${requireMatch[2]}`; - importLines.push(asImport); + if (line.match(RE_REQUIRE)) { + outputLines.push(line.replace(RE_REQUIRE, `import {$1} from $2`)); + } else if (line.match(RE_START_SNIPPET)) { + outputLines.push(line.replace(RE_START_SNIPPET, `[START modular_$1]`)); + } else if (line.match(RE_END_SNIPPET)) { + outputLines.push( + line.replace(RE_END_SNIPPET, `[END ${snippetPrefix}$1]`) + ); } else { - otherLines.push(line); + outputLines.push(line); } } // Adjust indentation of the otherLines so that they're left aligned - const nonBlankLines = otherLines.filter((l) => !isBlank(l)); + const nonBlankLines = outputLines.filter((l) => !isBlank(l)); const indentSizes = nonBlankLines.map((l) => l.length - l.trimLeft().length); const minIndent = Math.min(...indentSizes); - const adjustedOtherLines: string[] = []; - for (const line of otherLines) { + const adjustedOutputLines: string[] = []; + for (const line of outputLines) { if (isBlank(line)) { - adjustedOtherLines.push(""); + adjustedOutputLines.push(""); } else { - adjustedOtherLines.push(line.substr(minIndent)); + adjustedOutputLines.push(line.substr(minIndent)); } } // Special case: if the first line after the comments is blank we want to remove it - const firstNonComment = adjustedOtherLines.findIndex( + const firstNonComment = adjustedOutputLines.findIndex( (l) => !l.startsWith("//") ); - if (isBlank(otherLines[firstNonComment])) { - adjustedOtherLines.splice(firstNonComment, 1); + if (isBlank(outputLines[firstNonComment])) { + adjustedOutputLines.splice(firstNonComment, 1); } - // TODO: Should we add a preamble? - const content = [...importLines, ...adjustedOtherLines].join("\n"); + const preambleLines = [ + `// This snippet file was generated by processing the source file:`, + `// ${sourceFile}`, + `//`, + `// To make edits to the snippets in this file, please edit the source`, + ``, + ]; + const content = [...preambleLines, ...adjustedOutputLines].join("\n"); return content; } @@ -75,13 +109,29 @@ function listSnippetFiles(): string[] { * Collect all the snippets from a file into a map of snippet name to lines. * @param filePath the file path to read. */ -function collectSnippets(filePath: string): { [name: string]: string[] } { +function collectSnippets(filePath: string): SnippetsConfig { const fileContents = fs.readFileSync(filePath).toString(); const lines = fileContents.split("\n"); + const config: SnippetsConfig = { + enabled: false, + prefix: DEFAULT_PREFIX, + map: {}, + }; + + config.enabled = lines.some((l) => !!l.match(RE_SNIPPETS_SEPARATION)); + if (!config.enabled) { + return config; + } + + const prefixLine = lines.find((l) => !!l.match(RE_SNIPPETS_PREFIX)); + if (prefixLine) { + const m = prefixLine.match(RE_SNIPPETS_PREFIX); + config.prefix = m[1]; + } + let currSnippetName = ""; let inSnippet = false; - const snippetLines: { [name: string]: string[] } = {}; for (const line of lines) { const startMatch = line.match(RE_START_SNIPPET); const endMatch = line.match(RE_END_SNIPPET); @@ -89,11 +139,11 @@ function collectSnippets(filePath: string): { [name: string]: string[] } { if (startMatch) { inSnippet = true; currSnippetName = startMatch[1]; - snippetLines[currSnippetName] = []; + config.map[currSnippetName] = []; } if (inSnippet) { - snippetLines[currSnippetName].push(line); + config.map[currSnippetName].push(line); } if (endMatch) { @@ -106,29 +156,39 @@ function collectSnippets(filePath: string): { [name: string]: string[] } { } } - return snippetLines; + return config; } async function main() { const fileNames = listSnippetFiles(); for (const filePath of fileNames) { + const config = collectSnippets(filePath); + if (!config.enabled) { + continue; + } + const fileSlug = filePath .replace(".js", "") .replace("./", "") .replace(/\./g, "-"); const snippetDir = path.join("./snippets", fileSlug); - console.log(`Processing: ${filePath} --> ${snippetDir}`); + console.log( + `Processing: ${filePath} --> ${snippetDir} (prefix=${config.prefix})` + ); if (!fs.existsSync(snippetDir)) { fs.mkdirSync(snippetDir, { recursive: true }); } - const snippetLines = collectSnippets(filePath); - for (const snippetName in snippetLines) { + for (const snippetName in config.map) { const filePath = path.join(snippetDir, `${snippetName}.js`); - const content = processSnippet(snippetLines[snippetName]); + const content = processSnippet( + config.map[snippetName], + filePath, + config.prefix + ); fs.writeFileSync(filePath, content); } } diff --git a/snippets/README.md b/snippets/README.md index 8dc6a751..3819e7cf 100644 --- a/snippets/README.md +++ b/snippets/README.md @@ -1,3 +1,26 @@ -# Ignore this folder +# Generated Snippets -This folder contains generated files based on the source in other folders! +## Overview + +This directory contains snippets generated by the `separate-snippets` script. +Snippets in this folder should **never** be updated directly instead please +edit the source file (indicated by a comment at the top). + +## Regenerating the Snippets + +Run `npm run snippets` from the root of this repository. + +## Using the Separator + +For a file to be included in the separator script it must contain a comment like this: + +```js +// [SNIPPETS_SEPARATION enabled] +``` + +By default separated snippets will have their name prefixed with `modular_` +but you can override this with a commment: + +```js +// [SNIPPETS_PREFIX banana] +``` From f7cc641985960bcece1a328c243469b3d60c04eb Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 13:45:33 +0100 Subject: [PATCH 13/22] Restore old Firestore snippets --- firestore/emulator-suite.js | 18 +- firestore/next/emulator-suite.js | 17 + firestore/next/test.firestore.js | 1191 +++++++++++++++++ firestore/next/test.solution-aggregation.js | 41 + firestore/next/test.solution-arrays.js | 100 ++ firestore/next/test.solution-counters.js | 97 ++ firestore/test.firestore.js | 1272 +++++++++---------- firestore/test.solution-aggregation.js | 45 +- firestore/test.solution-arrays.js | 70 +- firestore/test.solution-counters.js | 75 +- 10 files changed, 2142 insertions(+), 784 deletions(-) create mode 100644 firestore/next/emulator-suite.js create mode 100644 firestore/next/test.firestore.js create mode 100644 firestore/next/test.solution-aggregation.js create mode 100644 firestore/next/test.solution-arrays.js create mode 100644 firestore/next/test.solution-counters.js diff --git a/firestore/emulator-suite.js b/firestore/emulator-suite.js index 6e608dc7..87b8f50d 100644 --- a/firestore/emulator-suite.js +++ b/firestore/emulator-suite.js @@ -1,17 +1,15 @@ -// [SNIPPETS_SEPARATION enabled] -function onDocumentReady(firebaseApp) { - // [START fs_emulator_connect] - const { initializeFirestore } = require("firebase/firestore"); +const firebase = require('firebase'); +require('firebase/firestore'); - let settings = {}; +function onDocumentReady(firebaseApp) { + //[START fs_emulator_connect] + // Firebase previously initialized using firebase.initializeApp(). + var db = firebase.firestore(); if (location.hostname === "localhost") { - settings = { + db.settings({ host: "localhost:8080", ssl: false - }; + }); } - - // firebaseApps previously initialized using initializeApp() - const db = initializeFirestore(firebaseApp, settings); // [END fs_emulator_connect] } diff --git a/firestore/next/emulator-suite.js b/firestore/next/emulator-suite.js new file mode 100644 index 00000000..6e608dc7 --- /dev/null +++ b/firestore/next/emulator-suite.js @@ -0,0 +1,17 @@ +// [SNIPPETS_SEPARATION enabled] +function onDocumentReady(firebaseApp) { + // [START fs_emulator_connect] + const { initializeFirestore } = require("firebase/firestore"); + + let settings = {}; + if (location.hostname === "localhost") { + settings = { + host: "localhost:8080", + ssl: false + }; + } + + // firebaseApps previously initialized using initializeApp() + const db = initializeFirestore(firebaseApp, settings); + // [END fs_emulator_connect] +} diff --git a/firestore/next/test.firestore.js b/firestore/next/test.firestore.js new file mode 100644 index 00000000..bcd5e7ef --- /dev/null +++ b/firestore/next/test.firestore.js @@ -0,0 +1,1191 @@ +// [SNIPPETS_SEPARATION enabled] +const { expect } = require('chai'); + +// [START city_custom_object] +class City { + constructor (name, state, country ) { + this.name = name; + this.state = state; + this.country = country; + } + toString() { + return this.name + ', ' + this.state + ', ' + this.country; + } +} + +// Firestore data converter +var cityConverter = { + toFirestore: function(city) { + return { + name: city.name, + state: city.state, + country: city.country + } + }, + fromFirestore: function(snapshot, options){ + const data = snapshot.data(options); + return new City(data.name, data.state, data.country) + } +} +// [END city_custom_object] + +describe("firestore", () => { + const { FirebaseFirestore } = require("firebase/firestore"); + + /** @type {FirebaseFirestore} */ + let db; + let app; + + before(() => { + const { initializeApp } = require("firebase/app"); + const { getFirestore } = require("firebase/firestore"); + + const config = { + apiKey: "AIzaSyCM61mMr_iZnP1DzjT1PMB5vDGxfyWNM64", + authDomain: "firestore-snippets.firebaseapp.com", + projectId: "firestore-snippets" + }; + app = initializeApp(config); + db = getFirestore(app); + }); + + it("should be able to set the cache size", () => { + // [START fs_setup_cache] + const { initializeFirestore, CACHE_SIZE_UNLIMITED } = require("firebase/firestore"); + + const firestoreDb = initializeFirestore(app, { + cacheSizeBytes: CACHE_SIZE_UNLIMITED + }); + // [END fs_setup_cache] + }); + + it("should be initializable with persistence", () => { + const { initializeApp } = require("firebase/app"); + const { getFirestore } = require("firebase/firestore"); + + const app = initializeApp({ + apiKey: '### FIREBASE API KEY ###', + authDomain: '### FIREBASE AUTH DOMAIN ###', + projectId: '### CLOUD FIRESTORE PROJECT ID ###', + } ,"persisted_app"); + + const db = getFirestore(app); + + // [START initialize_persistence] + const { enableIndexedDbPersistence } = require("firebase/firestore"); + + enableIndexedDbPersistence(db) + .catch((err) => { + if (err.code == 'failed-precondition') { + // Multiple tabs open, persistence can only be enabled + // in one tab at a a time. + // ... + } else if (err.code == 'unimplemented') { + // The current browser does not support all of the + // features required to enable persistence + // ... + } + }); + // Subsequent queries will use persistence, if it was enabled successfully + // [END initialize_persistence] + }); + + it("should be able to enable/disable network", async () => { + // [START disable_network] + const { disableNetwork } = require("firebase/firestore"); + + await disableNetwork(db); + console.log("Network disabled!"); + // Do offline actions + // [START_EXCLUDE] + console.log("Network disabled!"); + // [END_EXCLUDE] + // [END disable_network] + + // [START enable_network] + const { enableNetwork } = require("firebase/firestore"); + + await enableNetwork(db) + // Do online actions + // [START_EXCLUDE] + console.log("Network enabled!"); + // [END_EXCLUDE] + // [END enable_network] + + }); + + it("should reply with .fromCache fields", () => { + // [START use_from_cache] + const { collection, onSnapshot, where, query } = require("firebase/firestore"); + + const q = query(collection(db, "cities"), where("state", "==", "CA")); + onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => { + snapshot.docChanges().forEach((change) => { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + + const source = snapshot.metadata.fromCache ? "local cache" : "server"; + console.log("Data came from " + source); + }); + }); + // [END use_from_cache] + }); + + describe("collection('users')", () => { + it("should add data to a collection", async () => { + // [START add_ada_lovelace] + const { collection, addDoc } = require("firebase/firestore"); + + try { + const docRef = await addDoc(collection(db, "users"), { + first: "Ada", + last: "Lovelace", + born: 1815 + }); + console.log("Document written with ID: ", docRef.id); + } catch (e) { + console.error("Error adding document: ", e); + } + // [END add_ada_lovelace] + }); + + it("should get all users", async () => { + // [START get_all_users] + const { collection, getDocs } = require("firebase/firestore"); + + const querySnapshot = await getDocs(collection(db, "users")); + querySnapshot.forEach((doc) => { + console.log(`${doc.id} => ${doc.data()}`); + }); + // [END get_all_users] + }); + + it("should add data to a collection with new fields", async () => { + // [START add_alan_turing] + // Add a second document with a generated ID. + const { addDoc, collection } = require("firebase/firestore"); + + try { + const docRef = await addDoc(collection(db, "users"), { + first: "Alan", + middle: "Mathison", + last: "Turing", + born: 1912 + }); + + console.log("Document written with ID: ", docRef.id); + } catch (e) { + console.error("Error adding document: ", e); + } + // [END add_alan_turing] + }); + + it("should loop through a watched collection", (done) => { + // [START listen_for_users] + const { collection, where, query, onSnapshot } = require("firebase/firestore"); + + const q = query(collection(db, "users"), where("born", "<", 1900)); + const unsubscribe = onSnapshot(q, (snapshot) => { + console.log("Current users born before 1900:"); + snapshot.forEach(function (userSnapshot) { + console.log(userSnapshot.data()) + }); + }); + // [END listen_for_users] + + setTimeout(() => { + unsubscribe(); + done(); + }, 1500); + }); + + it("should reference a specific document", () => { + // [START doc_reference] + const { collection, doc } = require("firebase/firestore"); + + const alovelaceDocumentRef = doc(collection(db, 'users'), 'alovelace'); + // [END doc_reference] + }); + + it("should reference a specific collection", () => { + // [START collection_reference] + const { collection } = require("firebase/firestore"); + + const usersCollectionRef = collection(db, 'users'); + // [END collection_reference] + }); + + it("should reference a specific document (alternative)", () => { + // [START doc_reference_alternative] + const { doc } = require("firebase/firestore"); + + const alovelaceDocumentRef = doc(db, 'users/alovelace'); + // [END doc_reference_alternative] + }) + + it("should reference a document in a subcollection", () => { + // [START subcollection_reference] + const { doc, collection } = require("firebase/firestore"); + + const messageRef = doc(collection(doc(collection(db, "rooms"), "roomA"), "messages"), "message1"); + // [END subcollection_reference] + }); + + it("should set a document", async () => { + // [START set_document] + const { doc, collection, setDoc } = require("firebase/firestore"); + + // Add a new document in collection "cities" + await setDoc(doc(collection(db, "cities"), "LA"), { + name: "Los Angeles", + state: "CA", + country: "USA" + }); + // [END set_document] + }); + + it("should set document with a custom object converter", async () => { + // [START set_custom_object] + const { doc, collection, setDoc } = require("firebase/firestore"); + + // Set with cityConverter + const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); + await setDoc(ref, new City("Los Angeles", "CA", "USA")); + // [END set_custom_object] + }); + + it("should get document with a custom object converter", async () => { + // [START get_custom_object] + const { doc, collection, getDoc} = require("firebase/firestore"); + + const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); + const docSnap = await getDoc(ref); + if (docSnap.exists()) { + // Convert to City object + const city = docSnap.data(); + // Use a City instance method + console.log(city.toString()); + } else { + console.log("No such document!") + } + // [END get_custom_object] + }); + + it("should support batch writes", async () => { + // [START write_batch] + const { writeBatch, doc, collection } = require("firebase/firestore"); + + // Get a new write batch + const batch = writeBatch(db); + + // Set the value of 'NYC' + const nycRef = doc(collection(db, "cities"), "NYC"); + batch.set(nycRef, {name: "New York City"}); + + // Update the population of 'SF' + const sfRef = doc(collection(db, "cities"), "SF"); + batch.update(sfRef, {"population": 1000000}); + + // Delete the city 'LA' + const laRef = doc(collection(db, "cities"), "LA"); + batch.delete(laRef); + + // Commit the batch + await batch.commit(); + // [END write_batch] + }); + + it("should set a document with every datatype #UNVERIFIED", async () => { + // [START data_types] + const { doc, collection, setDoc, Timestamp } = require("firebase/firestore"); + + const docData = { + stringExample: "Hello world!", + booleanExample: true, + numberExample: 3.14159265, + dateExample: Timestamp.fromDate(new Date("December 10, 1815")), + arrayExample: [5, true, "hello"], + nullExample: null, + objectExample: { + a: 5, + b: { + nested: "foo" + } + } + }; + await setDoc(doc(collection(db, "data"), "one"), docData); + // [END data_types] + }); + + it("should allow set with merge", async () => { + // [START set_with_merge] + const { doc, collection, setDoc } = require("firebase/firestore"); + + const cityRef = doc(collection(db, 'cities'), 'BJ'); + setDoc(cityRef, { capital: true }, { merge: true }); + // [END set_with_merge] + }); + + it("should update a document's nested fields #UNVERIFIED", async () => { + // [START update_document_nested] + const { doc, collection, setDoc, updateDoc } = require("firebase/firestore"); + + // Create an initial document to update. + const frankDocRef = doc(collection(db, "users"), "frank"); + await setDoc(frankDocRef, { + name: "Frank", + favorites: { food: "Pizza", color: "Blue", subject: "recess" }, + age: 12 + }); + + // To update age and favorite color: + await updateDoc(frankDocRef, { + "age": 13, + "favorites.color": "Red" + }); + // [END update_document_nested] + }); + + it("should delete a collection", () => { + // [START delete_collection] + /** + * Delete a collection, in batches of batchSize. Note that this does + * not recursively delete subcollections of documents in the collection + */ + const { collection, query, orderBy, limit, getDocs, writeBatch } = require("firebase/firestore"); + + function deleteCollection(db, collectionRef, batchSize) { + const q = query(collectionRef, orderBy('__name__'), limit(batchSize)) + + return new Promise(function(resolve) { + deleteQueryBatch(db, q, batchSize, resolve); + }); + } + + async function deleteQueryBatch(db, query, batchSize, resolve) { + const snapshot = await getDocs(query); + + // When there are no documents left, we are done + let numDeleted = 0; + if (snapshot.size > 0) { + // Delete documents in a batch + const batch = writeBatch(db); + snapshot.docs.forEach((doc) => { + batch.delete(doc.ref); + }); + + await batch.commit(); + numDeleted = snapshot.size; + } + + if (numDeleted < batchSize) { + resolve(); + return; + } + + // Recurse on the next process tick, to avoid + // exploding the stack. + setTimeout(() => { + deleteQueryBatch(db, query, batchSize, resolve); + }, 0); + } + // [END delete_collection] + + return deleteCollection(db, collection(db, "users"), 2); + }).timeout(2000); + }); + + describe("collection('cities')", () => { + it("should set documents", async () => { + // [START example_data] + const { collection, doc, setDoc } = require("firebase/firestore"); + + const citiesRef = collection(db, "cities"); + + await setDoc(doc(citiesRef, "SF"), { + name: "San Francisco", state: "CA", country: "USA", + capital: false, population: 860000, + regions: ["west_coast", "norcal"] }); + await setDoc(doc(citiesRef, "LA"), { + name: "Los Angeles", state: "CA", country: "USA", + capital: false, population: 3900000, + regions: ["west_coast", "socal"] }); + await setDoc(doc(citiesRef, "DC"), { + name: "Washington, D.C.", state: null, country: "USA", + capital: true, population: 680000, + regions: ["east_coast"] }); + await setDoc(doc(citiesRef, "TOK"), { + name: "Tokyo", state: null, country: "Japan", + capital: true, population: 9000000, + regions: ["kanto", "honshu"] }); + await setDoc(doc(citiesRef, "BJ"), { + name: "Beijing", state: null, country: "China", + capital: true, population: 21500000, + regions: ["jingjinji", "hebei"] }); + // [END example_data] + }); + it("should set a document", async () => { + const data = {}; + + // [START cities_document_set] + const { collection, doc, setDoc } = require("firebase/firestore"); + + await setDoc(doc(collection(db, "cities"), "new-city-id"), data); + // [END cities_document_set] + }); + + it("should add a document", async () => { + // [START add_document] + const { collection, addDoc } = require("firebase/firestore"); + + // Add a new document with a generated id. + const docRef = await addDoc(collection(db, "cities"), { + name: "Tokyo", + country: "Japan" + }); + console.log("Document written with ID: ", docRef.id); + // [END add_document] + }); + + it("should add an empty a document", async () => { + const data = {}; + // [START new_document] + const { collection, doc, setDoc } = require("firebase/firestore"); + + // Add a new document with a generated id + const newCityRef = doc(collection(db, "cities")); + + // later... + await setDoc(newCityRef, data); + // [END new_document] + }); + + it("should update a document", async () => { + const data = {}; + // [START update_document] + const { collection, doc, updateDoc } = require("firebase/firestore"); + + const washingtonRef = doc(collection(db, "cities"), "DC"); + + // Set the "capital" field of the city 'DC' + await updateDoc(washingtonRef, { + capital: true + }); + // [END update_document] + }); + + it("should update an array field in a document", async () => { + // [START update_document_array] + const { collection, doc, updateDoc, arrayUnion, arrayRemove } = require("firebase/firestore"); + + const washingtonRef = doc(collection(db, "cities"), "DC"); + + // Atomically add a new region to the "regions" array field. + await updateDoc(washingtonRef, { + regions: arrayUnion("greater_virginia") + }); + + // Atomically remove a region from the "regions" array field. + await updateDoc(washingtonRef, { + regions: arrayRemove("east_coast") + }); + // [END update_document_array] + }); + + it("should update a document using numeric transforms", async () => { + // [START update_document_increment] + const { collection, doc, updateDoc, increment } = require("firebase/firestore"); + + const washingtonRef = doc(collection(db, "cities"), "DC"); + + // Atomically increment the population of the city by 50. + await updateDoc(washingtonRef, { + population: increment(50) + }); + // [END update_document_increment] + }) + + it("should delete a document", async () => { + // [START delete_document] + const { collection, doc, deleteDoc } = require("firebase/firestore"); + + await deleteDoc(doc(collection(db, "cities"), "DC")); + // [END delete_document] + }); + + it("should handle transactions", async () => { + const { collection, doc, setDoc } = require("firebase/firestore"); + + const sfDocRef = doc(collection(db, "cities"), "SF"); + await setDoc(sfDocRef, { population: 0 }); + + // [START transaction] + const { runTransaction } = require("firebase/firestore"); + + try { + await runTransaction(db, async (transaction) => { + const sfDoc = await transaction.get(sfDocRef); + if (!sfDoc.exists()) { + throw "Document does not exist!"; + } + + const newPopulation = sfDoc.data().population + 1; + transaction.update(sfDocRef, { population: newPopulation }); + }); + console.log("Transaction successfully committed!"); + } catch (e) { + console.log("Transaction failed: ", e); + } + // [END transaction] + }); + + it("should handle transaction which bubble out data", async () => { + // [START transaction_promise] + const { collection, doc, runTransaction } = require("firebase/firestore"); + + // Create a reference to the SF doc. + const sfDocRef = doc(collection(db, "cities"), "SF"); + + try { + const newPopulation = await runTransaction(db, async (transaction) => { + const sfDoc = await transaction.get(sfDocRef); + if (!sfDoc.exists()) { + throw "Document does not exist!"; + } + + const newPop = sfDoc.data().population + 1; + if (newPop <= 1000000) { + transaction.update(sfDocRef, { population: newPop }); + } else { + return Promise.reject("Sorry! Population is too big"); + } + }); + + console.log("Population increased to ", newPopulation); + } catch (e) { + // This will be a "population is too big" error. + console.error(e); + } + // [END transaction_promise] + }); + + it("should get a single document", async () => { + // [START get_document] + const { collection, doc, getDoc } = require("firebase/firestore"); + + const docRef = doc(collection(db, "cities"), "SF"); + const docSnap = await getDoc(docRef); + + if (docSnap.exists()) { + console.log("Document data:", docSnap.data()); + } else { + // doc.data() will be undefined in this case + console.log("No such document!"); + } + // [END get_document] + }); + + it("should get a document with options", async () => { + // [START get_document_options] + const { collection, doc, getDocFromCache } = require("firebase/firestore"); + + const docRef = doc(collection(db, "cities"), "SF"); + + // Get a document, forcing the SDK to fetch from the offline cache. + try { + const doc = await getDocFromCache(docRef); + + // Document was found in the cache. If no cached document exists, + // an error will be returned to the 'catch' block below. + console.log("Cached document data:", doc.data()); + } catch (e) { + console.log("Error getting cached document:", e); + } + // [END get_document_options] + }); + + it("should listen on a single document", (done) => { + // [START listen_document] + const { collection, doc, onSnapshot } = require("firebase/firestore"); + + const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { + console.log("Current data: ", doc.data()); + }); + // [END listen_document] + + setTimeout(function() { + unsub(); + done(); + }, 3000); + }).timeout(5000); + + it("should listen on a single document with metadata", (done) => { + // [START listen_document_local] + const { collection, doc, onSnapshot } = require("firebase/firestore"); + + const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { + const source = doc.metadata.hasPendingWrites ? "Local" : "Server"; + console.log(source, " data: ", doc.data()); + }); + // [END listen_document_local] + + setTimeout(function() { + unsub(); + done(); + }, 3000); + }).timeout(5000); + + it("should listen on a single document with options #UNVERIFIED", (done) => { + // [START listen_with_metadata] + const { collection, doc, onSnapshot } = require("firebase/firestore"); + + const unsub = onSnapshot( + doc(collection(db, "cities"), "SF"), + { includeMetadataChanges: true }, + (doc) => { + // ... + }); + // [END listen_with_metadata] + + setTimeout(function() { + unsub(); + done(); + }, 3000); + }).timeout(5000); + + it("should get multiple documents from a collection", async () => { + // [START get_multiple] + const { collection, query, where, getDocs } = require("firebase/firestore"); + + const q = query(collection(db, "cities"), where("capital", "==", true)); + + const querySnapshot = await getDocs(q); + querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); + }); + // [END get_multiple] + }).timeout(5000); + + it("should get all documents from a collection", async () => { + // [START get_multiple_all] + const { collection, getDocs } = require("firebase/firestore"); + + const querySnapshot = await getDocs(collection(db, "cities")); + querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); + }); + // [END get_multiple_all] + }); + + it("should listen on multiple documents #UNVERIFIED", (done) => { + // [START listen_multiple] + const { collection, query, where, onSnapshot } = require("firebase/firestore"); + + const q = query(collection(db, "cities"), where("state", "==", "CA")); + const unsubscribe = onSnapshot(q, (querySnapshot) => { + const cities = []; + querySnapshot.forEach((doc) => { + cities.push(doc.data().name); + }); + console.log("Current cities in CA: ", cities.join(", ")); + }); + // [END listen_multiple] + setTimeout(function() { + unsubscribe(); + done(); + }, 2500); + }).timeout(5000); + + it("should view changes between snapshots #UNVERIFIED", (done) => { + // [START listen_diffs] + const { collection, query, where, onSnapshot } = require("firebase/firestore"); + + const q = query(collection(db, "cities"), where("state", "==", "CA")); + const unsubscribe = onSnapshot(q, (snapshot) => { + snapshot.docChanges().forEach((change) => { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + if (change.type === "modified") { + console.log("Modified city: ", change.doc.data()); + } + if (change.type === "removed") { + console.log("Removed city: ", change.doc.data()); + } + }); + }); + // [END listen_diffs] + setTimeout(function() { + unsubscribe(); + done(); + }, 2500); + }).timeout(5000); + + it("should unsubscribe a listener", () => { + // [START detach_listener] + const { collection, onSnapshot } = require("firebase/firestore"); + + const unsubscribe = onSnapshot(collection(db, "cities"), () => { + // Respond to data + // ... + }); + + // Later ... + + // Stop listening to changes + unsubscribe(); + // [END detach_listener] + }); + + it("should handle listener errors", () => { + // [START handle_listen_errors] + const { collection, onSnapshot } = require("firebase/firestore"); + + const unsubscribe = onSnapshot( + collection(db, "cities"), + (snapshot) => { + // ... + }, + (error) => { + // ... + }); + // [END handle_listen_errors] + unsubscribe(); + }); + + it("should update a document with server timestamp", async () => { + async function update() { + // [START update_with_server_timestamp] + const { collection, updateDoc, serverTimestamp } = require("firebase/firestore"); + + const docRef = doc(collection(db, 'objects'), 'some-id'); + + // Update the timestamp field with the value from the server + const updateTimestamp = await updateDoc(docRef, { + timestamp: serverTimestamp() + }); + // [END update_with_server_timestamp] + + return updateTimestamp; + } + + const { collection, doc, setDoc } = require("firebase/firestore"); + + await setDoc(doc(collection(db, 'objects'), 'some-id'), {}); + await update(); + console.log('Document updated with server timestamp'); + }); + + it("should use options to control server timestamp resolution", async () => { + // [START server_timestamp_resolution_options] + const { collection, doc, updateDoc, serverTimestamp, onSnapshot } = require("firebase/firestore"); + // Perform an update followed by an immediate read without + // waiting for the update to complete. Due to the snapshot + // options we will get two results: one with an estimate + // timestamp and one with the resolved server timestamp. + const docRef = doc(collection(db, 'objects'), 'some-id'); + updateDoc(docRef, { + timestamp: serverTimestamp() + }); + + onSnapshot(docRef, (snapshot) => { + const data = snapshot.data({ + // Options: 'estimate', 'previous', or 'none' + serverTimestamps: "estimate" + }); + console.log( + 'Timestamp: ' + data.timestamp + + ', pending: ' + snapshot.metadata.hasPendingWrites); + }); + // [END server_timestamp_resolution_options] + }); + + it("should delete a document field", async () => { + async function update() { + // [START update_delete_field] + const { doc, collection, updateDoc, deleteField } = require("firebase/firestore"); + + const cityRef = doc(collection(db, 'cities'), 'BJ'); + + // Remove the 'capital' field from the document + await updateDoc(cityRef, { + capital: deleteField() + }); + // [END update_delete_field] + } + + const { doc, collection, setDoc } = require("firebase/firestore"); + + await setDoc(doc(collection(db,'cities'), 'BJ'), { capital: true }); + await update(); + }); + + describe("queries", () => { + it("should handle simple where", () => { + // [START simple_queries] + // Create a reference to the cities collection + const { collection, query, where } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // Create a query against the collection. + const q = query(citiesRef, where("state", "==", "CA")); + // [END simple_queries] + }); + + it("should handle another simple where", () => { + // [START simple_queries_again] + const { collection, query, where } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + const q = query(citiesRef, where("capital", "==", true)); + // [END simple_queries_again] + }); + + it("should handle other wheres", () => { + const { collection, query, where } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START example_filters] + const q1 = query(citiesRef, where("state", "==", "CA")); + const q2 = query(citiesRef, where("population", "<", 100000)); + const q3 = query(citiesRef, where("name", ">=", "San Francisco")); + // [END example_filters] + }); + + it("should handle array-contains where", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START array_contains_filter] + const { query, where } = require("firebase/firestore"); + const q = query(citiesRef, where("regions", "array-contains", "west_coast")); + // [END array_contains_filter] + }); + + it("should handle an array contains any where", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START array_contains_any_filter] + const { query, where } = require("firebase/firestore"); + + const q = query(citiesRef, + where('regions', 'array-contains-any', ['west_coast', 'east_coast'])); + // [END array_contains_any_filter] + }); + + it("should handle an in where", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + function inFilter() { + // [START in_filter] + const { query, where } = require("firebase/firestore"); + + const q = query(citiesRef, where('country', 'in', ['USA', 'Japan'])); + // [END in_filter] + } + + function inFilterWithArray() { + // [START in_filter_with_array] + const { query, where } = require("firebase/firestore"); + + const q = query(citiesRef, where('regions', 'in', [['west_coast', 'east_coast']])); + // [END in_filter_with_array] + } + }); + + it("should handle compound queries", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START chain_filters] + const { query, where } = require("firebase/firestore"); + + const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); + const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000)); + // [END chain_filters] + }); + + it("should handle range filters on one field", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START valid_range_filters] + const { query, where } = require("firebase/firestore"); + + const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); + const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000)); + // [END valid_range_filters] + }); + + it("should not handle range filters on multiple field", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + expect(() => { + // [START invalid_range_filters] + const { query, where } = require("firebase/firestore"); + + const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000)); + // [END invalid_range_filters] + }).to.throw; + }); + + it("should order and limit", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_limit] + const { query, orderBy, limit } = require("firebase/firestore"); + + const q = query(citiesRef, orderBy("name"), limit(3)); + // [END order_and_limit] + }); + + it("should order descending", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_limit_desc] + const { query, orderBy, limit } = require("firebase/firestore"); + + const q = query(citiesRef, orderBy("name", "desc"), limit(3)); + // [END order_and_limit_desc] + }); + + it("should order descending by other field", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_multiple] + const { query, orderBy } = require("firebase/firestore"); + + const q = query(citiesRef, orderBy("state"), orderBy("population", "desc")); + // [END order_multiple] + }); + + it("should where and order by with limit", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START filter_and_order] + const { query, where, orderBy, limit } = require("firebase/firestore"); + + const q = query(citiesRef, where("population", ">", 100000), orderBy("population"), limit(2)); + // [END filter_and_order] + }); + + it("should where and order on same field", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START valid_filter_and_order] + const { query, where, orderBy } = require("firebase/firestore"); + + const q = query(citiesRef, where("population", ">", 100000), orderBy("population")); + // [END valid_filter_and_order] + }); + + it("should not where and order on same field", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + expect(() => { + // [START invalid_filter_and_order] + const { query, where, orderBy } = require("firebase/firestore"); + + const q = query(citiesRef, where("population", ">", 100000), orderBy("country")); + // [END invalid_filter_and_order] + }).to.throw; + }); + + it("should handle startAt", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_start] + const { query, orderBy, startAt } = require("firebase/firestore"); + + const q = query(citiesRef, orderBy("population"), startAt(1000000)); + // [END order_and_start] + }); + + it("should handle endAt", () => { + const { collection } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + // [START order_and_end] + const { query, orderBy, endAt } = require("firebase/firestore"); + + const q = query(citiesRef, orderBy("population"), endAt(1000000)); + // [END order_and_end] + }); + + it("should handle startAt(doc) ", async () => { + // [START start_doc] + const { collection, doc, getDoc, query, orderBy, startAt } = require("firebase/firestore"); + const citiesRef = collection(db, "cities"); + + const docSnap = await getDoc(doc(citiesRef, "SF")); + + // Get all cities with a population bigger than San Francisco + const biggerThanSf = query(citiesRef, orderBy("popuation"), startAt(docSnap)); + // ... + // [END start_doc] + }); + + it("should handle multiple orderBy", () => { + // [START start_multiple_orderby] + // Will return all Springfields + const { collection, query, orderBy, startAt } = require("firebase/firestore"); + const q1 = query(collection(db, "cities"), + orderBy("name"), + orderBy("state"), + startAt("Springfield")); + + // Will return "Springfield, Missouri" and "Springfield, Wisconsin" + const q2 = query(collection(db, "cities"), + orderBy("name"), + orderBy("state"), + startAt("Springfield", "Missouri")); + // [END start_multiple_orderby] + }); + + it("should paginate", async () => { + // [START paginate] + const { collection, query, orderBy, startAfter, limit, getDocs } = require("firebase/firestore"); + + // Query the first page of docs + const first = query(collection(db, "cities"), orderBy("population"), limit(25)); + const documentSnapshots = await getDocs(first); + + // Get the last visible document + const lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; + console.log("last", lastVisible); + + // Construct a new query starting at this document, + // get the next 25 cities. + const next = query(collection(db, "cities"), + orderBy("population"), + startAfter(lastVisible), + limit(25)); + // [END paginate] + }); + }); + + describe('collectionGroup(landmarks)', () => { + it("should setup example data", async () => { + // [START fs_collection_group_query_data_setup] + const { collection, doc, setDoc } = require("firebase/firestore"); + + const citiesRef = collection(db, 'cities'); + + await Promise.all([ + setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { + name: 'Golden Gate Bridge', + type: 'bridge' + }), + setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { + name: 'Legion of Honor', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { + name: 'Griffith Park', + type: 'park' + }), + setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { + name: 'The Getty', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { + name: 'Lincoln Memorial', + type: 'memorial' + }), + setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { + name: 'National Air and Space Museum', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { + name: 'Ueno Park', + type: 'park' + }), + setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { + name: 'National Museum of Nature and Science', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { + name: 'Jingshan Park', + type: 'park' + }), + setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { + name: 'Beijing Ancient Observatory', + type: 'museum' + }) + ]); + // [END fs_collection_group_query_data_setup] + }); + + it("should query a collection group", async () => { + // [START fs_collection_group_query] + const { collectionGroup, query, where, getDocs } = require("firebase/firestore"); + + const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum')); + const querySnapshot = await getDocs(museums); + querySnapshot.forEach((doc) => { + console.log(doc.id, ' => ', doc.data()); + }); + // [END fs_collection_group_query] + }); + }); + }); + + // TODO: Break out into separate file + describe("solution-aggregation", () => { + it("should update a restaurant in a transaction #UNVERIFIED", async () => { + // [START add_rating_transaction] + const { collection, doc, runTransaction} = require("firebase/firestore"); + + async function addRating(restaurantRef, rating) { + // Create a reference for a new rating, for use inside the transaction + const ratingRef = doc(collection(restaurantRef, 'ratings')); + + // In a transaction, add the new rating and update the aggregate totals + await runTransaction(db, async (transaction) => { + const res = await transaction.get(restaurantRef); + if (!res.exists()) { + throw "Document does not exist!"; + } + + // Compute new number of ratings + const newNumRatings = res.data().numRatings + 1; + + // Compute new average rating + const oldRatingTotal = res.data().avgRating * res.data().numRatings; + const newAvgRating = (oldRatingTotal + rating) / newNumRatings; + + // Commit to Firestore + transaction.update(restaurantRef, { + numRatings: newNumRatings, + avgRating: newAvgRating + }); + transaction.set(ratingRef, { rating: rating }); + }); + } + // [END add_rating_transaction] + + // Create document and add a rating + const { setDoc } = require("firebase/firestore"); + const ref = doc(collection(db, 'restaurants'), ('arinell-pizza')); + await setDoc(ref, { + name: 'Arinell Pizza', + avgRating: 4.63, + numRatings: 683 + }); + await addRating(ref, 5.0); + }); + }); +}); diff --git a/firestore/next/test.solution-aggregation.js b/firestore/next/test.solution-aggregation.js new file mode 100644 index 00000000..a2b8c487 --- /dev/null +++ b/firestore/next/test.solution-aggregation.js @@ -0,0 +1,41 @@ +// [SNIPPETS_SEPARATION enabled] +// [START sample_doc] +const arinellDoc = { + name: 'Arinell Pizza', + avgRating: 4.65, + numRatings: 683 +} +// [END sample_doc] + +describe("firestore-solution-arrays", () => { + const { FirebaseFirestore } = require("firebase/firestore"); + + /** @type {FirebaseFirestore} */ + let db; + + before(async () => { + const { initializeApp } = require("firebase/app"); + const { getFirestore, collection, doc, setDoc } = require("firebase/firestore"); + + const config = { + apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", + authDomain: "firestorequickstarts.firebaseapp.com", + projectId: "firestorequickstarts", + }; + const app = initializeApp(config, "solution-arrays"); + db = getFirestore(app); + + await setDoc(doc(collection(db, "restaurants"), "arinell-pizza"), arinellDoc); + }); + + describe("solution-arrays", () => { + it("should get a collection of ratings", async () => { + // [START get_collection_ratings] + const { collection, doc, getDocs } = require("firebase/firestore"); + + const ratingsRef = collection(doc(collection(db, "restaurants"), "arinell-pizza"), "ratings"); + const ratingsDocs = await getDocs(ratingsRef); + // [END get_collection_ratings] + }) + }); +}); diff --git a/firestore/next/test.solution-arrays.js b/firestore/next/test.solution-arrays.js new file mode 100644 index 00000000..7c2ee04d --- /dev/null +++ b/firestore/next/test.solution-arrays.js @@ -0,0 +1,100 @@ +// [SNIPPETS_SEPARATION enabled] +const postsWithArray = [ + // [START post_with_array] + // Sample document in the 'posts' collection. + { + title: "My great post", + categories: [ + "technology", + "opinion", + "cats" + ] + } + // [END post_with_array] +]; + +const postsWithMap = [ + // [START post_with_map] + // Sample document in the 'posts' collection + { + title: "My great post", + categories: { + "technology": true, + "opinion": true, + "cats": true + } + } + // [END post_with_map] +]; + +const postsWithMapAdvanced = [ + // [START post_with_map_advanced] + // The value of each entry in 'categories' is a unix timestamp + { + title: "My great post", + categories: { + technology: 1502144665, + opinion: 1502144665, + cats: 1502144665 + } + } + // [END post_with_map_advanced] +] + +describe("firestore-solution-arrays", () => { + const { FirebaseFirestore } = require("firebase/firestore"); + + /** @type {FirebaseFirestore} */ + let db; + + before(() => { + const { initializeApp } = require("firebase/app"); + const { getFirestore } = require("firebase/firestore"); + + const config = { + apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", + authDomain: "firestorequickstarts.firebaseapp.com", + projectId: "firestorequickstarts", + }; + const app = initializeApp(config, "solution-arrays"); + db = getFirestore(app); + }); + + describe("solution-arrays", () => { + it("should query in a category", async () => { + // [START query_in_category] + const { collection, getDocs, query, where } = require("firebase/firestore"); + + // Find all documents in the 'posts' collection that are + // in the 'cats' category. + const q = query(collection(db, "posts"), where("categories.cats", "==", true)); + const docs = await getDocs(q); + // ... + // [END query_in_category] + }); + + it("should query in a category by timestamp", () => { + function queryOne() { + // [START query_in_category_timestamp_invalid] + const { collection, query, where, orderBy, FirebaseFirestore } = require("@firebase/firestore"); + + const q = query(collection(db, "posts"), + where("categories.cats", "==", true), + orderBy("timestamp")); + // [END query_in_category_timestamp_invalid] + } + + + function queryTwo() { + // [START query_in_category_timestamp] + const { collection, query, where, orderBy } = require("@firebase/firestore"); + + const q = query(collection(db, "posts"), + where("categories.cats", ">", 0), + orderBy("categories.cats")); + // [END query_in_category_timestamp] + } + + }); + }); +}); diff --git a/firestore/next/test.solution-counters.js b/firestore/next/test.solution-counters.js new file mode 100644 index 00000000..ab9eae36 --- /dev/null +++ b/firestore/next/test.solution-counters.js @@ -0,0 +1,97 @@ +// [SNIPPETS_SEPARATION enabled] +const { FirebaseFirestore } = require('firebase/firestore'); + +/** @type {FirebaseFirestore} */ +let db; + +// [START create_counter] +function createCounter(ref, num_shards) { + const { collection, doc, writeBatch } = require("firebase/firestore"); + + const batch = writeBatch(db); + + // Initialize the counter document + batch.set(ref, { num_shards: num_shards }); + + // Initialize each shard with count=0 + for (let i = 0; i < num_shards; i++) { + const shardRef = doc(collection(ref, 'shards'), i.toString()); + batch.set(shardRef, { count: 0 }); + } + + // Commit the write batch + return batch.commit(); +} +// [END create_counter] + +// [START increment_counter] +function incrementCounter(db, ref, num_shards) { + const { collection, doc, updateDoc, increment, FirebaseFirestore } = require("@firebase/firestore"); + + // Select a shard of the counter at random + const shardId = Math.floor(Math.random() * num_shards).toString(); + const shardRef = doc(collection(ref, 'shards'), shardId); + + // Update count + return updateDoc(shardRef, "count", increment(1)); +} +// [END increment_counter] + +// [START get_count] +async function getCount(ref) { + const { collection, getDocs } = require("@firebase/firestore"); + + // Sum the count of each shard in the subcollection + const snapshot = await getDocs(collection(ref, 'shards')); + + let totalCount = 0; + snapshot.forEach(doc => { + totalCount += doc.data().count; + }); + + return totalCount; +} +// [END get_count] + +describe("firestore-solution-counters", () => { + before(() => { + const { initializeApp } = require("firebase/app"); + const { getFirestore } = require("firebase/firestore"); + + const config = { + apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", + authDomain: "firestorequickstarts.firebaseapp.com", + projectId: "firestorequickstarts", + }; + const app = initializeApp(config, "solution-arrays"); + db = getFirestore(app); + }); + + describe("solution-counters", () => { + it("should create a counter", () => { + // Create a counter with 10 shards + const { collection, doc } = require("firebase/firestore"); + + return createCounter(doc(collection(db, 'counters')), 10); + }); + + it("should increment a counter", async () => { + // Create a counter, then increment it + const { collection, doc } = require("firebase/firestore"); + + const ref = doc(collection(db, 'counters')); + await createCounter(ref, 10) + await incrementCounter(db, ref, 10); + }); + + it("should get the count of a counter", async () => { + // Create a counter, increment it, then get the count + const { collection, doc } = require("firebase/firestore"); + + const ref = doc(collection(db, 'counters')); + await createCounter(ref, 10); + await incrementCounter(db, ref, 10); + await getCount(ref); + }); + }); +}); diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index bcd5e7ef..f5131965 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -1,5 +1,6 @@ -// [SNIPPETS_SEPARATION enabled] +var firebase = require('firebase/app'); const { expect } = require('chai'); +require('firebase/firestore'); // [START city_custom_object] class City { @@ -30,52 +31,36 @@ var cityConverter = { // [END city_custom_object] describe("firestore", () => { - const { FirebaseFirestore } = require("firebase/firestore"); - - /** @type {FirebaseFirestore} */ - let db; - let app; - + var db; before(() => { - const { initializeApp } = require("firebase/app"); - const { getFirestore } = require("firebase/firestore"); - - const config = { + var config = { apiKey: "AIzaSyCM61mMr_iZnP1DzjT1PMB5vDGxfyWNM64", authDomain: "firestore-snippets.firebaseapp.com", projectId: "firestore-snippets" }; - app = initializeApp(config); - db = getFirestore(app); + var app = firebase.initializeApp(config); + db = firebase.firestore(app); + //firebase.firestore.setLogLevel("debug"); }); it("should be able to set the cache size", () => { // [START fs_setup_cache] - const { initializeFirestore, CACHE_SIZE_UNLIMITED } = require("firebase/firestore"); - - const firestoreDb = initializeFirestore(app, { - cacheSizeBytes: CACHE_SIZE_UNLIMITED + firebase.firestore().settings({ + cacheSizeBytes: firebase.firestore.CACHE_SIZE_UNLIMITED }); // [END fs_setup_cache] }); it("should be initializable with persistence", () => { - const { initializeApp } = require("firebase/app"); - const { getFirestore } = require("firebase/firestore"); - - const app = initializeApp({ + firebase.initializeApp({ apiKey: '### FIREBASE API KEY ###', authDomain: '### FIREBASE AUTH DOMAIN ###', projectId: '### CLOUD FIRESTORE PROJECT ID ###', } ,"persisted_app"); - const db = getFirestore(app); - // [START initialize_persistence] - const { enableIndexedDbPersistence } = require("firebase/firestore"); - - enableIndexedDbPersistence(db) - .catch((err) => { + firebase.firestore().enablePersistence() + .catch(function(err) { if (err.code == 'failed-precondition') { // Multiple tabs open, persistence can only be enabled // in one tab at a a time. @@ -90,108 +75,112 @@ describe("firestore", () => { // [END initialize_persistence] }); - it("should be able to enable/disable network", async () => { - // [START disable_network] - const { disableNetwork } = require("firebase/firestore"); - - await disableNetwork(db); - console.log("Network disabled!"); - // Do offline actions - // [START_EXCLUDE] - console.log("Network disabled!"); - // [END_EXCLUDE] - // [END disable_network] - - // [START enable_network] - const { enableNetwork } = require("firebase/firestore"); - - await enableNetwork(db) - // Do online actions - // [START_EXCLUDE] - console.log("Network enabled!"); - // [END_EXCLUDE] - // [END enable_network] + it("should be able to enable/disable network", () => { + var disable = + // [START disable_network] + firebase.firestore().disableNetwork() + .then(function() { + // Do offline actions + // [START_EXCLUDE] + console.log("Network disabled!"); + // [END_EXCLUDE] + }); + // [END disable_network] + + var enable = + // [START enable_network] + firebase.firestore().enableNetwork() + .then(function() { + // Do online actions + // [START_EXCLUDE] + console.log("Network enabled!"); + // [END_EXCLUDE] + }); + // [END enable_network] + return Promise.all([enable, disable]); }); it("should reply with .fromCache fields", () => { // [START use_from_cache] - const { collection, onSnapshot, where, query } = require("firebase/firestore"); - - const q = query(collection(db, "cities"), where("state", "==", "CA")); - onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => { - snapshot.docChanges().forEach((change) => { - if (change.type === "added") { - console.log("New city: ", change.doc.data()); - } - - const source = snapshot.metadata.fromCache ? "local cache" : "server"; - console.log("Data came from " + source); - }); - }); + db.collection("cities").where("state", "==", "CA") + .onSnapshot({ includeMetadataChanges: true }, function(snapshot) { + snapshot.docChanges().forEach(function(change) { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + + var source = snapshot.metadata.fromCache ? "local cache" : "server"; + console.log("Data came from " + source); + }); + }); // [END use_from_cache] }); describe("collection('users')", () => { - it("should add data to a collection", async () => { + it("should add data to a collection", () => { + var output = // [START add_ada_lovelace] - const { collection, addDoc } = require("firebase/firestore"); - - try { - const docRef = await addDoc(collection(db, "users"), { + db.collection("users").add({ first: "Ada", last: "Lovelace", born: 1815 - }); - console.log("Document written with ID: ", docRef.id); - } catch (e) { - console.error("Error adding document: ", e); - } + }) + .then(function(docRef) { + console.log("Document written with ID: ", docRef.id); + }) + .catch(function(error) { + console.error("Error adding document: ", error); + }); // [END add_ada_lovelace] + return output; }); - it("should get all users", async () => { + it("should get all users", () => { + var output = // [START get_all_users] - const { collection, getDocs } = require("firebase/firestore"); - - const querySnapshot = await getDocs(collection(db, "users")); - querySnapshot.forEach((doc) => { - console.log(`${doc.id} => ${doc.data()}`); + db.collection("users").get().then((querySnapshot) => { + querySnapshot.forEach((doc) => { + console.log(`${doc.id} => ${doc.data()}`); + }); }); // [END get_all_users] + return output; }); - it("should add data to a collection with new fields", async () => { + it("should add data to a collection with new fields", () => { + var output = // [START add_alan_turing] // Add a second document with a generated ID. - const { addDoc, collection } = require("firebase/firestore"); - - try { - const docRef = await addDoc(collection(db, "users"), { + db.collection("users").add({ first: "Alan", middle: "Mathison", last: "Turing", born: 1912 - }); - - console.log("Document written with ID: ", docRef.id); - } catch (e) { - console.error("Error adding document: ", e); - } + }) + .then(function(docRef) { + console.log("Document written with ID: ", docRef.id); + }) + .catch(function(error) { + console.error("Error adding document: ", error); + }); // [END add_alan_turing] + return output; }); it("should loop through a watched collection", (done) => { - // [START listen_for_users] - const { collection, where, query, onSnapshot } = require("firebase/firestore"); + // This is not a typo. + var unsubscribe = - const q = query(collection(db, "users"), where("born", "<", 1900)); - const unsubscribe = onSnapshot(q, (snapshot) => { - console.log("Current users born before 1900:"); - snapshot.forEach(function (userSnapshot) { - console.log(userSnapshot.data()) + // [START listen_for_users] + db.collection("users") + .where("born", "<", 1900) + .onSnapshot(function(snapshot) { + console.log("Current users born before 1900:"); + snapshot.forEach(function (userSnapshot) { + console.log(userSnapshot.data()) + }); }); - }); // [END listen_for_users] setTimeout(() => { @@ -202,109 +191,112 @@ describe("firestore", () => { it("should reference a specific document", () => { // [START doc_reference] - const { collection, doc } = require("firebase/firestore"); - - const alovelaceDocumentRef = doc(collection(db, 'users'), 'alovelace'); + var alovelaceDocumentRef = db.collection('users').doc('alovelace'); // [END doc_reference] }); it("should reference a specific collection", () => { // [START collection_reference] - const { collection } = require("firebase/firestore"); - - const usersCollectionRef = collection(db, 'users'); + var usersCollectionRef = db.collection('users'); // [END collection_reference] }); it("should reference a specific document (alternative)", () => { // [START doc_reference_alternative] - const { doc } = require("firebase/firestore"); - - const alovelaceDocumentRef = doc(db, 'users/alovelace'); + var alovelaceDocumentRef = db.doc('users/alovelace'); // [END doc_reference_alternative] }) it("should reference a document in a subcollection", () => { // [START subcollection_reference] - const { doc, collection } = require("firebase/firestore"); - - const messageRef = doc(collection(doc(collection(db, "rooms"), "roomA"), "messages"), "message1"); + var messageRef = db.collection('rooms').doc('roomA') + .collection('messages').doc('message1'); // [END subcollection_reference] }); - it("should set a document", async () => { + it("should set a document", () => { + var output = // [START set_document] - const { doc, collection, setDoc } = require("firebase/firestore"); - // Add a new document in collection "cities" - await setDoc(doc(collection(db, "cities"), "LA"), { - name: "Los Angeles", - state: "CA", - country: "USA" + db.collection("cities").doc("LA").set({ + name: "Los Angeles", + state: "CA", + country: "USA" + }) + .then(function() { + console.log("Document successfully written!"); + }) + .catch(function(error) { + console.error("Error writing document: ", error); }); // [END set_document] + return output; }); - it("should set document with a custom object converter", async () => { + it("should set document with a custom object converter", () => { + var output = // [START set_custom_object] - const { doc, collection, setDoc } = require("firebase/firestore"); - // Set with cityConverter - const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); - await setDoc(ref, new City("Los Angeles", "CA", "USA")); + db.collection("cities").doc("LA") + .withConverter(cityConverter) + .set(new City("Los Angeles", "CA", "USA")); // [END set_custom_object] + return output; }); - it("should get document with a custom object converter", async () => { + it("should get document with a custom object converter", () => { + var output = // [START get_custom_object] - const { doc, collection, getDoc} = require("firebase/firestore"); - - const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); - const docSnap = await getDoc(ref); - if (docSnap.exists()) { - // Convert to City object - const city = docSnap.data(); - // Use a City instance method - console.log(city.toString()); - } else { - console.log("No such document!") - } + db.collection("cities").doc("LA") + .withConverter(cityConverter) + .get().then(function(doc) { + if (doc.exists){ + // Convert to City object + var city = doc.data(); + // Use a City instance method + console.log(city.toString()); + } else { + console.log("No such document!") + }}).catch(function(error) { + console.log("Error getting document:", error) + }); // [END get_custom_object] + return output; }); - it("should support batch writes", async () => { + it("should support batch writes", (done) => { // [START write_batch] - const { writeBatch, doc, collection } = require("firebase/firestore"); - // Get a new write batch - const batch = writeBatch(db); + var batch = db.batch(); // Set the value of 'NYC' - const nycRef = doc(collection(db, "cities"), "NYC"); + var nycRef = db.collection("cities").doc("NYC"); batch.set(nycRef, {name: "New York City"}); // Update the population of 'SF' - const sfRef = doc(collection(db, "cities"), "SF"); + var sfRef = db.collection("cities").doc("SF"); batch.update(sfRef, {"population": 1000000}); // Delete the city 'LA' - const laRef = doc(collection(db, "cities"), "LA"); + var laRef = db.collection("cities").doc("LA"); batch.delete(laRef); // Commit the batch - await batch.commit(); + batch.commit().then(function () { + // [START_EXCLUDE] + done(); + // [END_EXCLUDE] + }); // [END write_batch] }); - it("should set a document with every datatype #UNVERIFIED", async () => { + it("should set a document with every datatype #UNVERIFIED", () => { // [START data_types] - const { doc, collection, setDoc, Timestamp } = require("firebase/firestore"); - - const docData = { + var docData = { stringExample: "Hello world!", booleanExample: true, numberExample: 3.14159265, - dateExample: Timestamp.fromDate(new Date("December 10, 1815")), + dateExample: firebase.firestore.Timestamp.fromDate(new Date("December 10, 1815")), arrayExample: [5, true, "hello"], nullExample: null, objectExample: { @@ -314,35 +306,40 @@ describe("firestore", () => { } } }; - await setDoc(doc(collection(db, "data"), "one"), docData); + db.collection("data").doc("one").set(docData).then(function() { + console.log("Document successfully written!"); + }); // [END data_types] }); - it("should allow set with merge", async () => { + it("should allow set with merge", () => { // [START set_with_merge] - const { doc, collection, setDoc } = require("firebase/firestore"); + var cityRef = db.collection('cities').doc('BJ'); - const cityRef = doc(collection(db, 'cities'), 'BJ'); - setDoc(cityRef, { capital: true }, { merge: true }); + var setWithMerge = cityRef.set({ + capital: true + }, { merge: true }); // [END set_with_merge] + return setWithMerge; }); - it("should update a document's nested fields #UNVERIFIED", async () => { + it("should update a document's nested fields #UNVERIFIED", () => { // [START update_document_nested] - const { doc, collection, setDoc, updateDoc } = require("firebase/firestore"); - // Create an initial document to update. - const frankDocRef = doc(collection(db, "users"), "frank"); - await setDoc(frankDocRef, { + var frankDocRef = db.collection("users").doc("frank"); + frankDocRef.set({ name: "Frank", favorites: { food: "Pizza", color: "Blue", subject: "recess" }, age: 12 }); // To update age and favorite color: - await updateDoc(frankDocRef, { + db.collection("users").doc("frank").update({ "age": 13, "favorites.color": "Red" + }) + .then(function() { + console.log("Document successfully updated!"); }); // [END update_document_nested] }); @@ -353,265 +350,279 @@ describe("firestore", () => { * Delete a collection, in batches of batchSize. Note that this does * not recursively delete subcollections of documents in the collection */ - const { collection, query, orderBy, limit, getDocs, writeBatch } = require("firebase/firestore"); - function deleteCollection(db, collectionRef, batchSize) { - const q = query(collectionRef, orderBy('__name__'), limit(batchSize)) - - return new Promise(function(resolve) { - deleteQueryBatch(db, q, batchSize, resolve); - }); - } - - async function deleteQueryBatch(db, query, batchSize, resolve) { - const snapshot = await getDocs(query); + var query = collectionRef.orderBy('__name__').limit(batchSize); - // When there are no documents left, we are done - let numDeleted = 0; - if (snapshot.size > 0) { - // Delete documents in a batch - const batch = writeBatch(db); - snapshot.docs.forEach((doc) => { - batch.delete(doc.ref); + return new Promise(function(resolve, reject) { + deleteQueryBatch(db, query, batchSize, resolve, reject); }); + } - await batch.commit(); - numDeleted = snapshot.size; - } - - if (numDeleted < batchSize) { - resolve(); - return; - } - - // Recurse on the next process tick, to avoid - // exploding the stack. - setTimeout(() => { - deleteQueryBatch(db, query, batchSize, resolve); - }, 0); + function deleteQueryBatch(db, query, batchSize, resolve, reject) { + query.get() + .then((snapshot) => { + // When there are no documents left, we are done + if (snapshot.size == 0) { + return 0; + } + + // Delete documents in a batch + var batch = db.batch(); + snapshot.docs.forEach(function(doc) { + batch.delete(doc.ref); + }); + + return batch.commit().then(function() { + return snapshot.size; + }); + }).then(function(numDeleted) { + if (numDeleted < batchSize) { + resolve(); + return; + } + + // Recurse on the next process tick, to avoid + // exploding the stack. + setTimeout(function() { + deleteQueryBatch(db, query, batchSize, resolve, reject); + }, 0); + }) + .catch(reject); } // [END delete_collection] - return deleteCollection(db, collection(db, "users"), 2); + return deleteCollection(db, db.collection("users"), 2); }).timeout(2000); }); describe("collection('cities')", () => { - it("should set documents", async () => { + it("should set documents #UNVERIFIED", () => { // [START example_data] - const { collection, doc, setDoc } = require("firebase/firestore"); - - const citiesRef = collection(db, "cities"); + var citiesRef = db.collection("cities"); - await setDoc(doc(citiesRef, "SF"), { + citiesRef.doc("SF").set({ name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); - await setDoc(doc(citiesRef, "LA"), { + citiesRef.doc("LA").set({ name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); - await setDoc(doc(citiesRef, "DC"), { + citiesRef.doc("DC").set({ name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); - await setDoc(doc(citiesRef, "TOK"), { + citiesRef.doc("TOK").set({ name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); - await setDoc(doc(citiesRef, "BJ"), { + citiesRef.doc("BJ").set({ name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] }); // [END example_data] }); - it("should set a document", async () => { - const data = {}; - + it("should set a document", () => { + var data = {}; + var output = // [START cities_document_set] - const { collection, doc, setDoc } = require("firebase/firestore"); - - await setDoc(doc(collection(db, "cities"), "new-city-id"), data); + db.collection("cities").doc("new-city-id").set(data); // [END cities_document_set] + return output; }); - it("should add a document", async () => { + it("should add a document", () => { + var output = // [START add_document] - const { collection, addDoc } = require("firebase/firestore"); - // Add a new document with a generated id. - const docRef = await addDoc(collection(db, "cities"), { - name: "Tokyo", - country: "Japan" + db.collection("cities").add({ + name: "Tokyo", + country: "Japan" + }) + .then(function(docRef) { + console.log("Document written with ID: ", docRef.id); + }) + .catch(function(error) { + console.error("Error adding document: ", error); }); - console.log("Document written with ID: ", docRef.id); // [END add_document] + return output; }); - it("should add an empty a document", async () => { - const data = {}; + it("should add an empty a document #UNVERIFIED", () => { + var data = {}; // [START new_document] - const { collection, doc, setDoc } = require("firebase/firestore"); - - // Add a new document with a generated id - const newCityRef = doc(collection(db, "cities")); + // Add a new document with a generated id. + var newCityRef = db.collection("cities").doc(); // later... - await setDoc(newCityRef, data); + newCityRef.set(data); // [END new_document] }); - it("should update a document", async () => { - const data = {}; + it("should update a document", () => { + var data = {}; // [START update_document] - const { collection, doc, updateDoc } = require("firebase/firestore"); - - const washingtonRef = doc(collection(db, "cities"), "DC"); + var washingtonRef = db.collection("cities").doc("DC"); // Set the "capital" field of the city 'DC' - await updateDoc(washingtonRef, { - capital: true + return washingtonRef.update({ + capital: true + }) + .then(function() { + console.log("Document successfully updated!"); + }) + .catch(function(error) { + // The document probably doesn't exist. + console.error("Error updating document: ", error); }); // [END update_document] }); - it("should update an array field in a document", async () => { + it("should update an array field in a document", () => { // [START update_document_array] - const { collection, doc, updateDoc, arrayUnion, arrayRemove } = require("firebase/firestore"); - - const washingtonRef = doc(collection(db, "cities"), "DC"); + var washingtonRef = db.collection("cities").doc("DC"); // Atomically add a new region to the "regions" array field. - await updateDoc(washingtonRef, { - regions: arrayUnion("greater_virginia") + washingtonRef.update({ + regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia") }); // Atomically remove a region from the "regions" array field. - await updateDoc(washingtonRef, { - regions: arrayRemove("east_coast") + washingtonRef.update({ + regions: firebase.firestore.FieldValue.arrayRemove("east_coast") }); // [END update_document_array] }); - it("should update a document using numeric transforms", async () => { + it("should update a document using numeric transforms", () => { // [START update_document_increment] - const { collection, doc, updateDoc, increment } = require("firebase/firestore"); - - const washingtonRef = doc(collection(db, "cities"), "DC"); + var washingtonRef = db.collection('cities').doc('DC'); // Atomically increment the population of the city by 50. - await updateDoc(washingtonRef, { - population: increment(50) + washingtonRef.update({ + population: firebase.firestore.FieldValue.increment(50) }); // [END update_document_increment] }) - it("should delete a document", async () => { + it("should delete a document", () => { + var output = // [START delete_document] - const { collection, doc, deleteDoc } = require("firebase/firestore"); - - await deleteDoc(doc(collection(db, "cities"), "DC")); + db.collection("cities").doc("DC").delete().then(function() { + console.log("Document successfully deleted!"); + }).catch(function(error) { + console.error("Error removing document: ", error); + }); // [END delete_document] + return output; }); - it("should handle transactions", async () => { - const { collection, doc, setDoc } = require("firebase/firestore"); - - const sfDocRef = doc(collection(db, "cities"), "SF"); - await setDoc(sfDocRef, { population: 0 }); - - // [START transaction] - const { runTransaction } = require("firebase/firestore"); - - try { - await runTransaction(db, async (transaction) => { - const sfDoc = await transaction.get(sfDocRef); - if (!sfDoc.exists()) { - throw "Document does not exist!"; - } - - const newPopulation = sfDoc.data().population + 1; - transaction.update(sfDocRef, { population: newPopulation }); - }); - console.log("Transaction successfully committed!"); - } catch (e) { - console.log("Transaction failed: ", e); - } - // [END transaction] + it("should handle transactions #FIXME #UNVERIFIED", () => { + return db.collection("cities").doc("SF").set({ population: 0 }).then(() => { + // [START transaction] + // Create a reference to the SF doc. + var sfDocRef = db.collection("cities").doc("SF"); + + // Uncomment to initialize the doc. + // sfDocRef.set({ population: 0 }); + + return db.runTransaction(function(transaction) { + // This code may get re-run multiple times if there are conflicts. + return transaction.get(sfDocRef).then(function(sfDoc) { + if (!sfDoc.exists) { + throw "Document does not exist!"; + } + + // Add one person to the city population. + // Note: this could be done without a transaction + // by updating the population using FieldValue.increment() + var newPopulation = sfDoc.data().population + 1; + transaction.update(sfDocRef, { population: newPopulation }); + }); + }).then(function() { + console.log("Transaction successfully committed!"); + }).catch(function(error) { + console.log("Transaction failed: ", error); + }); + // [END transaction] + }); }); - it("should handle transaction which bubble out data", async () => { + it("should handle transaction which bubble out data #UNVERIFIED", () => { // [START transaction_promise] - const { collection, doc, runTransaction } = require("firebase/firestore"); - // Create a reference to the SF doc. - const sfDocRef = doc(collection(db, "cities"), "SF"); - - try { - const newPopulation = await runTransaction(db, async (transaction) => { - const sfDoc = await transaction.get(sfDocRef); - if (!sfDoc.exists()) { - throw "Document does not exist!"; - } + var sfDocRef = db.collection("cities").doc("SF"); - const newPop = sfDoc.data().population + 1; - if (newPop <= 1000000) { - transaction.update(sfDocRef, { population: newPop }); - } else { - return Promise.reject("Sorry! Population is too big"); - } - }); + db.runTransaction(function(transaction) { + return transaction.get(sfDocRef).then(function(sfDoc) { + if (!sfDoc.exists) { + throw "Document does not exist!"; + } - console.log("Population increased to ", newPopulation); - } catch (e) { - // This will be a "population is too big" error. - console.error(e); - } + var newPopulation = sfDoc.data().population + 1; + if (newPopulation <= 1000000) { + transaction.update(sfDocRef, { population: newPopulation }); + return newPopulation; + } else { + return Promise.reject("Sorry! Population is too big."); + } + }); + }).then(function(newPopulation) { + console.log("Population increased to ", newPopulation); + }).catch(function(err) { + // This will be an "population is too big" error. + console.error(err); + }); // [END transaction_promise] }); - it("should get a single document", async () => { + it("should get a single document #UNVERIFIED", () => { // [START get_document] - const { collection, doc, getDoc } = require("firebase/firestore"); - - const docRef = doc(collection(db, "cities"), "SF"); - const docSnap = await getDoc(docRef); + var docRef = db.collection("cities").doc("SF"); - if (docSnap.exists()) { - console.log("Document data:", docSnap.data()); - } else { - // doc.data() will be undefined in this case - console.log("No such document!"); - } + docRef.get().then(function(doc) { + if (doc.exists) { + console.log("Document data:", doc.data()); + } else { + // doc.data() will be undefined in this case + console.log("No such document!"); + } + }).catch(function(error) { + console.log("Error getting document:", error); + }); // [END get_document] }); - it("should get a document with options", async () => { + it("should get a document with options #UNVERIFIED", () => { // [START get_document_options] - const { collection, doc, getDocFromCache } = require("firebase/firestore"); + var docRef = db.collection("cities").doc("SF"); - const docRef = doc(collection(db, "cities"), "SF"); + // Valid options for source are 'server', 'cache', or + // 'default'. See https://firebase.google.com/docs/reference/js/firebase.firestore.GetOptions + // for more information. + var getOptions = { + source: 'cache' + }; // Get a document, forcing the SDK to fetch from the offline cache. - try { - const doc = await getDocFromCache(docRef); - - // Document was found in the cache. If no cached document exists, - // an error will be returned to the 'catch' block below. - console.log("Cached document data:", doc.data()); - } catch (e) { - console.log("Error getting cached document:", e); - } + docRef.get(getOptions).then(function(doc) { + // Document was found in the cache. If no cached document exists, + // an error will be returned to the 'catch' block below. + console.log("Cached document data:", doc.data()); + }).catch(function(error) { + console.log("Error getting cached document:", error); + }); // [END get_document_options] }); it("should listen on a single document", (done) => { + var unsub = // [START listen_document] - const { collection, doc, onSnapshot } = require("firebase/firestore"); - - const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { - console.log("Current data: ", doc.data()); - }); + db.collection("cities").doc("SF") + .onSnapshot(function(doc) { + console.log("Current data: ", doc.data()); + }); // [END listen_document] setTimeout(function() { @@ -620,14 +631,14 @@ describe("firestore", () => { }, 3000); }).timeout(5000); - it("should listen on a single document with metadata", (done) => { + it("should listen on a single document with metadata #UNVERIFIED", (done) => { + var unsub = // [START listen_document_local] - const { collection, doc, onSnapshot } = require("firebase/firestore"); - - const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { - const source = doc.metadata.hasPendingWrites ? "Local" : "Server"; - console.log(source, " data: ", doc.data()); - }); + db.collection("cities").doc("SF") + .onSnapshot(function(doc) { + var source = doc.metadata.hasPendingWrites ? "Local" : "Server"; + console.log(source, " data: ", doc.data()); + }); // [END listen_document_local] setTimeout(function() { @@ -637,15 +648,15 @@ describe("firestore", () => { }).timeout(5000); it("should listen on a single document with options #UNVERIFIED", (done) => { + var unsub = // [START listen_with_metadata] - const { collection, doc, onSnapshot } = require("firebase/firestore"); - - const unsub = onSnapshot( - doc(collection(db, "cities"), "SF"), - { includeMetadataChanges: true }, - (doc) => { - // ... - }); + db.collection("cities").doc("SF") + .onSnapshot({ + // Listen for document metadata changes + includeMetadataChanges: true + }, function(doc) { + // ... + }); // [END listen_with_metadata] setTimeout(function() { @@ -654,44 +665,48 @@ describe("firestore", () => { }, 3000); }).timeout(5000); - it("should get multiple documents from a collection", async () => { + it("should get multiple documents from a collection", () => { + var output = // [START get_multiple] - const { collection, query, where, getDocs } = require("firebase/firestore"); - - const q = query(collection(db, "cities"), where("capital", "==", true)); - - const querySnapshot = await getDocs(q); - querySnapshot.forEach((doc) => { - // doc.data() is never undefined for query doc snapshots - console.log(doc.id, " => ", doc.data()); - }); + db.collection("cities").where("capital", "==", true) + .get() + .then(function(querySnapshot) { + querySnapshot.forEach(function(doc) { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); + }); + }) + .catch(function(error) { + console.log("Error getting documents: ", error); + }); // [END get_multiple] + return output; }).timeout(5000); - it("should get all documents from a collection", async () => { + it("should get all documents from a collection", () => { + var output = // [START get_multiple_all] - const { collection, getDocs } = require("firebase/firestore"); - - const querySnapshot = await getDocs(collection(db, "cities")); - querySnapshot.forEach((doc) => { - // doc.data() is never undefined for query doc snapshots - console.log(doc.id, " => ", doc.data()); + db.collection("cities").get().then(function(querySnapshot) { + querySnapshot.forEach(function(doc) { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); + }); }); // [END get_multiple_all] - }); + return output; + }) it("should listen on multiple documents #UNVERIFIED", (done) => { + var unsubscribe = // [START listen_multiple] - const { collection, query, where, onSnapshot } = require("firebase/firestore"); - - const q = query(collection(db, "cities"), where("state", "==", "CA")); - const unsubscribe = onSnapshot(q, (querySnapshot) => { - const cities = []; - querySnapshot.forEach((doc) => { - cities.push(doc.data().name); - }); - console.log("Current cities in CA: ", cities.join(", ")); - }); + db.collection("cities").where("state", "==", "CA") + .onSnapshot(function(querySnapshot) { + var cities = []; + querySnapshot.forEach(function(doc) { + cities.push(doc.data().name); + }); + console.log("Current cities in CA: ", cities.join(", ")); + }); // [END listen_multiple] setTimeout(function() { unsubscribe(); @@ -700,23 +715,22 @@ describe("firestore", () => { }).timeout(5000); it("should view changes between snapshots #UNVERIFIED", (done) => { + var unsubscribe = // [START listen_diffs] - const { collection, query, where, onSnapshot } = require("firebase/firestore"); - - const q = query(collection(db, "cities"), where("state", "==", "CA")); - const unsubscribe = onSnapshot(q, (snapshot) => { - snapshot.docChanges().forEach((change) => { - if (change.type === "added") { - console.log("New city: ", change.doc.data()); - } - if (change.type === "modified") { - console.log("Modified city: ", change.doc.data()); - } - if (change.type === "removed") { - console.log("Removed city: ", change.doc.data()); - } - }); - }); + db.collection("cities").where("state", "==", "CA") + .onSnapshot(function(snapshot) { + snapshot.docChanges().forEach(function(change) { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + if (change.type === "modified") { + console.log("Modified city: ", change.doc.data()); + } + if (change.type === "removed") { + console.log("Removed city: ", change.doc.data()); + } + }); + }); // [END listen_diffs] setTimeout(function() { unsubscribe(); @@ -726,12 +740,11 @@ describe("firestore", () => { it("should unsubscribe a listener", () => { // [START detach_listener] - const { collection, onSnapshot } = require("firebase/firestore"); - - const unsubscribe = onSnapshot(collection(db, "cities"), () => { - // Respond to data - // ... - }); + var unsubscribe = db.collection("cities") + .onSnapshot(function (){ + // Respond to data + // ... + }); // Later ... @@ -741,402 +754,334 @@ describe("firestore", () => { }); it("should handle listener errors", () => { + var unsubscribe = // [START handle_listen_errors] - const { collection, onSnapshot } = require("firebase/firestore"); - - const unsubscribe = onSnapshot( - collection(db, "cities"), - (snapshot) => { - // ... - }, - (error) => { - // ... - }); + db.collection("cities") + .onSnapshot(function(snapshot) { + //... + }, function(error) { + //... + }); // [END handle_listen_errors] unsubscribe(); }); - it("should update a document with server timestamp", async () => { - async function update() { + it("should update a document with server timestamp", () => { + function update() { // [START update_with_server_timestamp] - const { collection, updateDoc, serverTimestamp } = require("firebase/firestore"); - - const docRef = doc(collection(db, 'objects'), 'some-id'); + var docRef = db.collection('objects').doc('some-id'); // Update the timestamp field with the value from the server - const updateTimestamp = await updateDoc(docRef, { - timestamp: serverTimestamp() + var updateTimestamp = docRef.update({ + timestamp: firebase.firestore.FieldValue.serverTimestamp() }); // [END update_with_server_timestamp] return updateTimestamp; } - const { collection, doc, setDoc } = require("firebase/firestore"); - - await setDoc(doc(collection(db, 'objects'), 'some-id'), {}); - await update(); - console.log('Document updated with server timestamp'); + return db.collection('objects').doc('some-id') + .set({}) + .then(() => update()) + .then(() => { + console.log('Document updated with server timestamp'); + }); }); - it("should use options to control server timestamp resolution", async () => { - // [START server_timestamp_resolution_options] - const { collection, doc, updateDoc, serverTimestamp, onSnapshot } = require("firebase/firestore"); - // Perform an update followed by an immediate read without - // waiting for the update to complete. Due to the snapshot - // options we will get two results: one with an estimate - // timestamp and one with the resolved server timestamp. - const docRef = doc(collection(db, 'objects'), 'some-id'); - updateDoc(docRef, { - timestamp: serverTimestamp() - }); - - onSnapshot(docRef, (snapshot) => { - const data = snapshot.data({ - // Options: 'estimate', 'previous', or 'none' - serverTimestamps: "estimate" + it("should use options to control server timestamp resolution #UNVERIFIED", () => { + var options = { + // Options: 'estimate', 'previous', or 'none' + serverTimestamps: 'estimate' + }; + + // Perform an update followed by an immediate read without + // waiting for the update to complete. Due to the snapshot + // options we will get two results: one with an estimate + // timestamp and one with the resolved server timestamp. + var docRef = db.collection('objects').doc('some-id'); + docRef.update({ + timestamp: firebase.firestore.FieldValue.serverTimestamp() + }); + docRef.onSnapshot(function(snapshot) { + var data = snapshot.data(options); + console.log( + 'Timestamp: ' + data.timestamp + + ', pending: ' + snapshot.metadata.hasPendingWrites); }); - console.log( - 'Timestamp: ' + data.timestamp + - ', pending: ' + snapshot.metadata.hasPendingWrites); - }); - // [END server_timestamp_resolution_options] }); - it("should delete a document field", async () => { - async function update() { - // [START update_delete_field] - const { doc, collection, updateDoc, deleteField } = require("firebase/firestore"); + it("should delete a document field", () => { + function update() { + // [START update_delete_field] + var cityRef = db.collection('cities').doc('BJ'); - const cityRef = doc(collection(db, 'cities'), 'BJ'); + // Remove the 'capital' field from the document + var removeCapital = cityRef.update({ + capital: firebase.firestore.FieldValue.delete() + }); + // [END update_delete_field] - // Remove the 'capital' field from the document - await updateDoc(cityRef, { - capital: deleteField() - }); - // [END update_delete_field] + return removeCapital; } - const { doc, collection, setDoc } = require("firebase/firestore"); - await setDoc(doc(collection(db,'cities'), 'BJ'), { capital: true }); - await update(); + return db.collection('cities').doc('BJ') + .set({ capital: true }) + .then(() => update()) + .then(() => { + console.log('Document field deleted'); + }); }); describe("queries", () => { it("should handle simple where", () => { // [START simple_queries] // Create a reference to the cities collection - const { collection, query, where } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); + var citiesRef = db.collection("cities"); // Create a query against the collection. - const q = query(citiesRef, where("state", "==", "CA")); + var query = citiesRef.where("state", "==", "CA"); // [END simple_queries] }); it("should handle another simple where", () => { // [START simple_queries_again] - const { collection, query, where } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); + var citiesRef = db.collection("cities"); - const q = query(citiesRef, where("capital", "==", true)); + var query = citiesRef.where("capital", "==", true); // [END simple_queries_again] }); it("should handle other wheres", () => { - const { collection, query, where } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START example_filters] - const q1 = query(citiesRef, where("state", "==", "CA")); - const q2 = query(citiesRef, where("population", "<", 100000)); - const q3 = query(citiesRef, where("name", ">=", "San Francisco")); - // [END example_filters] + var citiesRef = db.collection("cities"); + // [START example_filters] + citiesRef.where("state", "==", "CA") + citiesRef.where("population", "<", 100000) + citiesRef.where("name", ">=", "San Francisco") + // [END example_filters] }); it("should handle array-contains where", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START array_contains_filter] - const { query, where } = require("firebase/firestore"); - const q = query(citiesRef, where("regions", "array-contains", "west_coast")); - // [END array_contains_filter] + var citiesRef = db.collection("cities"); + // [START array_contains_filter] + citiesRef.where("regions", "array-contains", "west_coast") + // [END array_contains_filter] }); it("should handle an array contains any where", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START array_contains_any_filter] - const { query, where } = require("firebase/firestore"); - - const q = query(citiesRef, - where('regions', 'array-contains-any', ['west_coast', 'east_coast'])); - // [END array_contains_any_filter] + const citiesRef = db.collection('cities'); + // [START array_contains_any_filter] + citiesRef.where('regions', 'array-contains-any', + ['west_coast', 'east_coast']); + // [END array_contains_any_filter] }); it("should handle an in where", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - function inFilter() { + const citiesRef = db.collection('cities'); // [START in_filter] - const { query, where } = require("firebase/firestore"); - - const q = query(citiesRef, where('country', 'in', ['USA', 'Japan'])); + citiesRef.where('country', 'in', ['USA', 'Japan']); // [END in_filter] - } - function inFilterWithArray() { // [START in_filter_with_array] - const { query, where } = require("firebase/firestore"); - - const q = query(citiesRef, where('regions', 'in', [['west_coast', 'east_coast']])); + citiesRef.where('regions', 'in', + [['west_coast', 'east_coast']]); // [END in_filter_with_array] - } }); it("should handle compound queries", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START chain_filters] - const { query, where } = require("firebase/firestore"); - - const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); - const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000)); - // [END chain_filters] + var citiesRef = db.collection("cities"); + // [START chain_filters] + citiesRef.where("state", "==", "CO").where("name", "==", "Denver"); + citiesRef.where("state", "==", "CA").where("population", "<", 1000000); + // [END chain_filters] }); it("should handle range filters on one field", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START valid_range_filters] - const { query, where } = require("firebase/firestore"); - - const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); - const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000)); - // [END valid_range_filters] + var citiesRef = db.collection("cities"); + // [START valid_range_filters] + citiesRef.where("state", ">=", "CA").where("state", "<=", "IN"); + citiesRef.where("state", "==", "CA").where("population", ">", 1000000); + // [END valid_range_filters] }); it("should not handle range filters on multiple field", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - expect(() => { - // [START invalid_range_filters] - const { query, where } = require("firebase/firestore"); - - const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000)); - // [END invalid_range_filters] - }).to.throw; + var citiesRef = db.collection("cities"); + expect(() => { + // [START invalid_range_filters] + citiesRef.where("state", ">=", "CA").where("population", ">", 100000); + // [END invalid_range_filters] + }).to.throw(); }); it("should order and limit", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START order_and_limit] - const { query, orderBy, limit } = require("firebase/firestore"); - - const q = query(citiesRef, orderBy("name"), limit(3)); - // [END order_and_limit] + var citiesRef = db.collection("cities"); + // [START order_and_limit] + citiesRef.orderBy("name").limit(3) + // [END order_and_limit] }); it("should order descending", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START order_and_limit_desc] - const { query, orderBy, limit } = require("firebase/firestore"); - - const q = query(citiesRef, orderBy("name", "desc"), limit(3)); - // [END order_and_limit_desc] + var citiesRef = db.collection("cities"); + // [START order_and_limit_desc] + citiesRef.orderBy("name", "desc").limit(3) + // [END order_and_limit_desc] }); it("should order descending by other field", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START order_multiple] - const { query, orderBy } = require("firebase/firestore"); - - const q = query(citiesRef, orderBy("state"), orderBy("population", "desc")); - // [END order_multiple] + var citiesRef = db.collection("cities"); + // [START order_multiple] + citiesRef.orderBy("state").orderBy("population", "desc") + // [END order_multiple] }); it("should where and order by with limit", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START filter_and_order] - const { query, where, orderBy, limit } = require("firebase/firestore"); - - const q = query(citiesRef, where("population", ">", 100000), orderBy("population"), limit(2)); - // [END filter_and_order] + var citiesRef = db.collection("cities"); + // [START filter_and_order] + citiesRef.where("population", ">", 100000).orderBy("population").limit(2) + // [END filter_and_order] }); it("should where and order on same field", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START valid_filter_and_order] - const { query, where, orderBy } = require("firebase/firestore"); - - const q = query(citiesRef, where("population", ">", 100000), orderBy("population")); - // [END valid_filter_and_order] + var citiesRef = db.collection("cities"); + // [START valid_filter_and_order] + citiesRef.where("population", ">", 100000).orderBy("population") + // [END valid_filter_and_order] }); it("should not where and order on same field", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - expect(() => { - // [START invalid_filter_and_order] - const { query, where, orderBy } = require("firebase/firestore"); - - const q = query(citiesRef, where("population", ">", 100000), orderBy("country")); - // [END invalid_filter_and_order] - }).to.throw; + var citiesRef = db.collection("cities"); + expect(() => { + // [START invalid_filter_and_order] + citiesRef.where("population", ">", 100000).orderBy("country") + // [END invalid_filter_and_order] + }).to.throw; }); it("should handle startAt", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - // [START order_and_start] - const { query, orderBy, startAt } = require("firebase/firestore"); - - const q = query(citiesRef, orderBy("population"), startAt(1000000)); - // [END order_and_start] + var citiesRef = db.collection("cities"); + // [START order_and_start] + citiesRef.orderBy("population").startAt(1000000) + // [END order_and_start] }); it("should handle endAt", () => { - const { collection } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); + var citiesRef = db.collection("cities"); + // [START order_and_end] + citiesRef.orderBy("population").endAt(1000000) + // [END order_and_end] + }); - // [START order_and_end] - const { query, orderBy, endAt } = require("firebase/firestore"); + it("should handle startAt(doc) ", () => { + // [START start_doc] + var citiesRef = db.collection("cities"); - const q = query(citiesRef, orderBy("population"), endAt(1000000)); - // [END order_and_end] - }); + return citiesRef.doc("SF").get().then(function(doc) { + // Get all cities with a population bigger than San Francisco + var biggerThanSf = citiesRef + .orderBy("population") + .startAt(doc); - it("should handle startAt(doc) ", async () => { - // [START start_doc] - const { collection, doc, getDoc, query, orderBy, startAt } = require("firebase/firestore"); - const citiesRef = collection(db, "cities"); - - const docSnap = await getDoc(doc(citiesRef, "SF")); - - // Get all cities with a population bigger than San Francisco - const biggerThanSf = query(citiesRef, orderBy("popuation"), startAt(docSnap)); - // ... - // [END start_doc] + // ... + }); + // [END start_doc] }); it("should handle multiple orderBy", () => { // [START start_multiple_orderby] // Will return all Springfields - const { collection, query, orderBy, startAt } = require("firebase/firestore"); - const q1 = query(collection(db, "cities"), - orderBy("name"), - orderBy("state"), - startAt("Springfield")); + db.collection("cities") + .orderBy("name") + .orderBy("state") + .startAt("Springfield") // Will return "Springfield, Missouri" and "Springfield, Wisconsin" - const q2 = query(collection(db, "cities"), - orderBy("name"), - orderBy("state"), - startAt("Springfield", "Missouri")); + db.collection("cities") + .orderBy("name") + .orderBy("state") + .startAt("Springfield", "Missouri") // [END start_multiple_orderby] }); - it("should paginate", async () => { + it("shoud paginate", () => { // [START paginate] - const { collection, query, orderBy, startAfter, limit, getDocs } = require("firebase/firestore"); - - // Query the first page of docs - const first = query(collection(db, "cities"), orderBy("population"), limit(25)); - const documentSnapshots = await getDocs(first); - - // Get the last visible document - const lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; - console.log("last", lastVisible); - - // Construct a new query starting at this document, - // get the next 25 cities. - const next = query(collection(db, "cities"), - orderBy("population"), - startAfter(lastVisible), - limit(25)); + var first = db.collection("cities") + .orderBy("population") + .limit(25); + + return first.get().then(function (documentSnapshots) { + // Get the last visible document + var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; + console.log("last", lastVisible); + + // Construct a new query starting at this document, + // get the next 25 cities. + var next = db.collection("cities") + .orderBy("population") + .startAfter(lastVisible) + .limit(25); + }); // [END paginate] }); }); - describe('collectionGroup(landmarks)', () => { - it("should setup example data", async () => { + describe('collectionGroup(landmarks', () => { + it("should setup example data", () => { // [START fs_collection_group_query_data_setup] - const { collection, doc, setDoc } = require("firebase/firestore"); - - const citiesRef = collection(db, 'cities'); + var citiesRef = db.collection('cities'); - await Promise.all([ - setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { + var landmarks = Promise.all([ + citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Golden Gate Bridge', type: 'bridge' }), - setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { + citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Legion of Honor', type: 'museum' }), - setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { + citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'Griffith Park', type: 'park' }), - setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { + citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'The Getty', type: 'museum' }), - setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { + citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'Lincoln Memorial', type: 'memorial' }), - setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { + citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'National Air and Space Museum', type: 'museum' }), - setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { + citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'Ueno Park', type: 'park' }), - setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { + citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'National Museum of Nature and Science', type: 'museum' }), - setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { + citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Jingshan Park', type: 'park' }), - setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { + citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Beijing Ancient Observatory', type: 'museum' }) ]); // [END fs_collection_group_query_data_setup] + return landmarks; }); - it("should query a collection group", async () => { + it("should query a collection group", () => { // [START fs_collection_group_query] - const { collectionGroup, query, where, getDocs } = require("firebase/firestore"); - - const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum')); - const querySnapshot = await getDocs(museums); - querySnapshot.forEach((doc) => { - console.log(doc.id, ' => ', doc.data()); + var museums = db.collectionGroup('landmarks').where('type', '==', 'museum'); + museums.get().then(function (querySnapshot) { + querySnapshot.forEach(function (doc) { + console.log(doc.id, ' => ', doc.data()); + }); }); // [END fs_collection_group_query] }); @@ -1145,47 +1090,46 @@ describe("firestore", () => { // TODO: Break out into separate file describe("solution-aggregation", () => { - it("should update a restaurant in a transaction #UNVERIFIED", async () => { + it("should update a restaurant in a transaction #UNVERIFIED", () => { // [START add_rating_transaction] - const { collection, doc, runTransaction} = require("firebase/firestore"); - - async function addRating(restaurantRef, rating) { + function addRating(restaurantRef, rating) { // Create a reference for a new rating, for use inside the transaction - const ratingRef = doc(collection(restaurantRef, 'ratings')); + var ratingRef = restaurantRef.collection('ratings').doc(); // In a transaction, add the new rating and update the aggregate totals - await runTransaction(db, async (transaction) => { - const res = await transaction.get(restaurantRef); - if (!res.exists()) { - throw "Document does not exist!"; - } - - // Compute new number of ratings - const newNumRatings = res.data().numRatings + 1; - - // Compute new average rating - const oldRatingTotal = res.data().avgRating * res.data().numRatings; - const newAvgRating = (oldRatingTotal + rating) / newNumRatings; - - // Commit to Firestore - transaction.update(restaurantRef, { - numRatings: newNumRatings, - avgRating: newAvgRating - }); - transaction.set(ratingRef, { rating: rating }); + return db.runTransaction(transaction => { + return transaction.get(restaurantRef).then(res => { + if (!res.exists) { + throw "Document does not exist!"; + } + + // Compute new number of ratings + var newNumRatings = res.data().numRatings + 1; + + // Compute new average rating + var oldRatingTotal = res.data().avgRating * res.data().numRatings; + var newAvgRating = (oldRatingTotal + rating) / newNumRatings; + + // Commit to Firestore + transaction.update(restaurantRef, { + numRatings: newNumRatings, + avgRating: newAvgRating + }); + transaction.set(ratingRef, { rating: rating }); + }) }); } // [END add_rating_transaction] // Create document and add a rating - const { setDoc } = require("firebase/firestore"); - const ref = doc(collection(db, 'restaurants'), ('arinell-pizza')); - await setDoc(ref, { + var ref = db.collection('restaurants').doc('arinell-pizza'); + return ref.set({ name: 'Arinell Pizza', avgRating: 4.63, numRatings: 683 + }).then(res => { + return addRating(ref, 5.0) }); - await addRating(ref, 5.0); }); }); }); diff --git a/firestore/test.solution-aggregation.js b/firestore/test.solution-aggregation.js index a2b8c487..6075561d 100644 --- a/firestore/test.solution-aggregation.js +++ b/firestore/test.solution-aggregation.js @@ -1,6 +1,8 @@ -// [SNIPPETS_SEPARATION enabled] +var firebase = require('firebase/app'); +require('firebase/firestore'); + // [START sample_doc] -const arinellDoc = { +var arinellDoc = { name: 'Arinell Pizza', avgRating: 4.65, numRatings: 683 @@ -8,33 +10,28 @@ const arinellDoc = { // [END sample_doc] describe("firestore-solution-arrays", () => { - const { FirebaseFirestore } = require("firebase/firestore"); - - /** @type {FirebaseFirestore} */ - let db; - - before(async () => { - const { initializeApp } = require("firebase/app"); - const { getFirestore, collection, doc, setDoc } = require("firebase/firestore"); + var db; + before(() => { + var config = { + apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", + authDomain: "firestorequickstarts.firebaseapp.com", + projectId: "firestorequickstarts", + }; + var app = firebase.initializeApp(config, "solution-arrays"); + db = firebase.firestore(app); - const config = { - apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", - authDomain: "firestorequickstarts.firebaseapp.com", - projectId: "firestorequickstarts", - }; - const app = initializeApp(config, "solution-arrays"); - db = getFirestore(app); - - await setDoc(doc(collection(db, "restaurants"), "arinell-pizza"), arinellDoc); + return db.collection("restaurants") + .doc("arinell-pizza") + .set(arinellDoc); }); describe("solution-arrays", () => { - it("should get a collection of ratings", async () => { + it("should get a collection of ratings", () => { // [START get_collection_ratings] - const { collection, doc, getDocs } = require("firebase/firestore"); - - const ratingsRef = collection(doc(collection(db, "restaurants"), "arinell-pizza"), "ratings"); - const ratingsDocs = await getDocs(ratingsRef); + db.collection("restaurants") + .doc("arinell-pizza") + .collection("ratings") + .get() // [END get_collection_ratings] }) }); diff --git a/firestore/test.solution-arrays.js b/firestore/test.solution-arrays.js index 7c2ee04d..4e1215ae 100644 --- a/firestore/test.solution-arrays.js +++ b/firestore/test.solution-arrays.js @@ -1,5 +1,7 @@ -// [SNIPPETS_SEPARATION enabled] -const postsWithArray = [ +var firebase = require('firebase/app'); +require('firebase/firestore'); + +let postsWithArray = [ // [START post_with_array] // Sample document in the 'posts' collection. { @@ -13,7 +15,7 @@ const postsWithArray = [ // [END post_with_array] ]; -const postsWithMap = [ +let postsWithMap = [ // [START post_with_map] // Sample document in the 'posts' collection { @@ -27,7 +29,7 @@ const postsWithMap = [ // [END post_with_map] ]; -const postsWithMapAdvanced = [ +let postsWithMapAdvanced = [ // [START post_with_map_advanced] // The value of each entry in 'categories' is a unix timestamp { @@ -42,59 +44,43 @@ const postsWithMapAdvanced = [ ] describe("firestore-solution-arrays", () => { - const { FirebaseFirestore } = require("firebase/firestore"); - - /** @type {FirebaseFirestore} */ - let db; - + var db; before(() => { - const { initializeApp } = require("firebase/app"); - const { getFirestore } = require("firebase/firestore"); - - const config = { + var config = { apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", authDomain: "firestorequickstarts.firebaseapp.com", projectId: "firestorequickstarts", }; - const app = initializeApp(config, "solution-arrays"); - db = getFirestore(app); + var app = firebase.initializeApp(config, "solution-arrays"); + db = firebase.firestore(app); }); describe("solution-arrays", () => { - it("should query in a category", async () => { + it("should query in a category #UNVERIFIED", () => { // [START query_in_category] - const { collection, getDocs, query, where } = require("firebase/firestore"); - // Find all documents in the 'posts' collection that are // in the 'cats' category. - const q = query(collection(db, "posts"), where("categories.cats", "==", true)); - const docs = await getDocs(q); - // ... + db.collection('posts') + .where('categories.cats', '==', true) + .get() + .then(() => { + // ... + }); // [END query_in_category] }); - it("should query in a category by timestamp", () => { - function queryOne() { - // [START query_in_category_timestamp_invalid] - const { collection, query, where, orderBy, FirebaseFirestore } = require("@firebase/firestore"); - - const q = query(collection(db, "posts"), - where("categories.cats", "==", true), - orderBy("timestamp")); - // [END query_in_category_timestamp_invalid] - } - - - function queryTwo() { - // [START query_in_category_timestamp] - const { collection, query, where, orderBy } = require("@firebase/firestore"); - - const q = query(collection(db, "posts"), - where("categories.cats", ">", 0), - orderBy("categories.cats")); - // [END query_in_category_timestamp] - } + it("should query in a category by timestamp #UNVERIFIED", () => { + // [START query_in_category_timestamp_invalid] + db.collection('posts') + .where('categories.cats', '==', true) + .orderBy('timestamp'); + // [END query_in_category_timestamp_invalid] + // [START query_in_category_timestamp] + db.collection('posts') + .where('categories.cats', '>', 0) + .orderBy('categories.cats'); + // [END query_in_category_timestamp] }); }); }); diff --git a/firestore/test.solution-counters.js b/firestore/test.solution-counters.js index ab9eae36..ef0fd3bc 100644 --- a/firestore/test.solution-counters.js +++ b/firestore/test.solution-counters.js @@ -1,21 +1,18 @@ -// [SNIPPETS_SEPARATION enabled] -const { FirebaseFirestore } = require('firebase/firestore'); +var firebase = require('firebase/app'); +require('firebase/firestore'); -/** @type {FirebaseFirestore} */ -let db; +var db; // [START create_counter] function createCounter(ref, num_shards) { - const { collection, doc, writeBatch } = require("firebase/firestore"); - - const batch = writeBatch(db); + var batch = db.batch(); // Initialize the counter document batch.set(ref, { num_shards: num_shards }); // Initialize each shard with count=0 for (let i = 0; i < num_shards; i++) { - const shardRef = doc(collection(ref, 'shards'), i.toString()); + let shardRef = ref.collection('shards').doc(i.toString()); batch.set(shardRef, { count: 0 }); } @@ -26,72 +23,62 @@ function createCounter(ref, num_shards) { // [START increment_counter] function incrementCounter(db, ref, num_shards) { - const { collection, doc, updateDoc, increment, FirebaseFirestore } = require("@firebase/firestore"); - // Select a shard of the counter at random - const shardId = Math.floor(Math.random() * num_shards).toString(); - const shardRef = doc(collection(ref, 'shards'), shardId); + const shard_id = Math.floor(Math.random() * num_shards).toString(); + const shard_ref = ref.collection('shards').doc(shard_id); // Update count - return updateDoc(shardRef, "count", increment(1)); + return shard_ref.update("count", firebase.firestore.FieldValue.increment(1)); } // [END increment_counter] // [START get_count] -async function getCount(ref) { - const { collection, getDocs } = require("@firebase/firestore"); - +function getCount(ref) { // Sum the count of each shard in the subcollection - const snapshot = await getDocs(collection(ref, 'shards')); + return ref.collection('shards').get().then(snapshot => { + let total_count = 0; + snapshot.forEach(doc => { + total_count += doc.data().count; + }); - let totalCount = 0; - snapshot.forEach(doc => { - totalCount += doc.data().count; + return total_count; }); - - return totalCount; } // [END get_count] describe("firestore-solution-counters", () => { before(() => { - const { initializeApp } = require("firebase/app"); - const { getFirestore } = require("firebase/firestore"); - - const config = { + var config = { apiKey: "AIzaSyArvVh6VSdXicubcvIyuB-GZs8ua0m0DTI", authDomain: "firestorequickstarts.firebaseapp.com", projectId: "firestorequickstarts", }; - const app = initializeApp(config, "solution-arrays"); - db = getFirestore(app); + var app = firebase.initializeApp(config, "solution-counters"); + db = firebase.firestore(app); }); describe("solution-counters", () => { it("should create a counter", () => { // Create a counter with 10 shards - const { collection, doc } = require("firebase/firestore"); - - return createCounter(doc(collection(db, 'counters')), 10); + return createCounter(db.collection('counters').doc(), 10); }); - it("should increment a counter", async () => { + it("should increment a counter", () => { // Create a counter, then increment it - const { collection, doc } = require("firebase/firestore"); - - const ref = doc(collection(db, 'counters')); - await createCounter(ref, 10) - await incrementCounter(db, ref, 10); + let ref = db.collection('counters').doc(); + return createCounter(ref, 10).then(() => { + return incrementCounter(db, ref, 10); + }); }); - it("should get the count of a counter", async () => { + it("should get the count of a counter", () => { // Create a counter, increment it, then get the count - const { collection, doc } = require("firebase/firestore"); - - const ref = doc(collection(db, 'counters')); - await createCounter(ref, 10); - await incrementCounter(db, ref, 10); - await getCount(ref); + let ref = db.collection('counters').doc(); + return createCounter(ref, 10).then(() => { + return incrementCounter(db, ref, 10); + }).then(() => { + return getCount(ref); + }); }); }); }); From 5582819ff48d7e59b63be3095a498da4d2f24a37 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 13:48:38 +0100 Subject: [PATCH 14/22] Make firestore-next --- .../next => firestore-next}/emulator-suite.js | 0 firestore-next/package.json | 17 +++++++++++++++++ .../next => firestore-next}/test.firestore.js | 0 .../test.solution-aggregation.js | 0 .../test.solution-arrays.js | 0 .../test.solution-counters.js | 0 firestore/package.json | 2 +- firestore/test.firestore.js | 5 +++-- lerna.json | 1 + 9 files changed, 22 insertions(+), 3 deletions(-) rename {firestore/next => firestore-next}/emulator-suite.js (100%) create mode 100644 firestore-next/package.json rename {firestore/next => firestore-next}/test.firestore.js (100%) rename {firestore/next => firestore-next}/test.solution-aggregation.js (100%) rename {firestore/next => firestore-next}/test.solution-arrays.js (100%) rename {firestore/next => firestore-next}/test.solution-counters.js (100%) diff --git a/firestore/next/emulator-suite.js b/firestore-next/emulator-suite.js similarity index 100% rename from firestore/next/emulator-suite.js rename to firestore-next/emulator-suite.js diff --git a/firestore-next/package.json b/firestore-next/package.json new file mode 100644 index 00000000..310f730b --- /dev/null +++ b/firestore-next/package.json @@ -0,0 +1,17 @@ +{ + "name": "firestore-next", + "version": "1.0.0", + "scripts": { + "compile": "cp ../tsconfig.json.template ./tsconfig.json && tsc" + }, + "license": "Apache-2.0", + "dependencies": { + "firebase": "^0.800.7" + }, + "devDependencies": { + "@types/chai": "^4.2.12", + "@types/mocha": "^8.0.3", + "chai": "^4.2.0", + "mocha": "^8.1.3" + } +} diff --git a/firestore/next/test.firestore.js b/firestore-next/test.firestore.js similarity index 100% rename from firestore/next/test.firestore.js rename to firestore-next/test.firestore.js diff --git a/firestore/next/test.solution-aggregation.js b/firestore-next/test.solution-aggregation.js similarity index 100% rename from firestore/next/test.solution-aggregation.js rename to firestore-next/test.solution-aggregation.js diff --git a/firestore/next/test.solution-arrays.js b/firestore-next/test.solution-arrays.js similarity index 100% rename from firestore/next/test.solution-arrays.js rename to firestore-next/test.solution-arrays.js diff --git a/firestore/next/test.solution-counters.js b/firestore-next/test.solution-counters.js similarity index 100% rename from firestore/next/test.solution-counters.js rename to firestore-next/test.solution-counters.js diff --git a/firestore/package.json b/firestore/package.json index f853a230..d9e1b2d6 100644 --- a/firestore/package.json +++ b/firestore/package.json @@ -6,7 +6,7 @@ }, "license": "Apache-2.0", "dependencies": { - "firebase": "^0.800.7" + "firebase": "^7.20.0" }, "devDependencies": { "@types/chai": "^4.2.12", diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index f5131965..b0dedce8 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -1,7 +1,8 @@ -var firebase = require('firebase/app'); -const { expect } = require('chai'); +const firebase = require('firebase/app'); require('firebase/firestore'); +const { expect } = require('chai'); + // [START city_custom_object] class City { constructor (name, state, country ) { diff --git a/lerna.json b/lerna.json index 1cf4129b..6ce5fc4a 100644 --- a/lerna.json +++ b/lerna.json @@ -5,6 +5,7 @@ "database", "firebaseapp", "firestore", + "firestore-next", "functions", "installations" ], From e12027ded3fe30717eccbfbfd9fa111c8212e087 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 13:53:32 +0100 Subject: [PATCH 15/22] Make functions-next --- {functions => functions-next}/.gitignore | 0 {functions/src => functions-next}/emulator-suite.js | 10 ++++++++-- functions-next/package.json | 12 ++++++++++++ functions/emulator-suite.js | 8 ++++++++ functions/package.json | 7 +------ functions/src/index.js | 1 - lerna.json | 1 + 7 files changed, 30 insertions(+), 9 deletions(-) rename {functions => functions-next}/.gitignore (100%) rename {functions/src => functions-next}/emulator-suite.js (68%) create mode 100644 functions-next/package.json create mode 100644 functions/emulator-suite.js delete mode 100644 functions/src/index.js diff --git a/functions/.gitignore b/functions-next/.gitignore similarity index 100% rename from functions/.gitignore rename to functions-next/.gitignore diff --git a/functions/src/emulator-suite.js b/functions-next/emulator-suite.js similarity index 68% rename from functions/src/emulator-suite.js rename to functions-next/emulator-suite.js index 8d4978f1..c2e1b535 100644 --- a/functions/src/emulator-suite.js +++ b/functions-next/emulator-suite.js @@ -1,5 +1,5 @@ -import { initializeApp, getApp } from "firebase/app"; -import { getFunctions, useFunctionsEmulator, httpsCallable } from "firebase/functions"; +// [SNIPPETS_SEPARATION enabled] +import { initializeApp } from "firebase/app"; initializeApp({ projectId: '### CLOUD FUNCTIONS PROJECT ID ###', @@ -9,6 +9,9 @@ initializeApp({ export function emulatorSettings() { // [START functions_emulator_connect] + const { getApp } = require("firebase/app"); + const { getFunctions, useFunctionsEmulator } = require( "firebase/functions"); + const functions = getFunctions(getApp()); useFunctionsEmulator(functions, "http://localhost:5001"); // [END functions_emulator_connect] @@ -16,6 +19,9 @@ export function emulatorSettings() { export async function callFunction() { // [START functions_callable_call] + const { getApp } = require("firebase/app"); + const { getFunctions, httpsCallable } = require( "firebase/functions"); + const functions = getFunctions(getApp()); const addMessage = httpsCallable(functions, 'addMessage'); diff --git a/functions-next/package.json b/functions-next/package.json new file mode 100644 index 00000000..cb5ad467 --- /dev/null +++ b/functions-next/package.json @@ -0,0 +1,12 @@ +{ + "name": "functions-next", + "version": "1.0.0", + "scripts": { + "build": "webpack", + "compile": "cp ../tsconfig.json.template ./tsconfig.json && tsc" + }, + "license": "Apache-2.0", + "dependencies": { + "firebase": "^0.800.3" + } +} diff --git a/functions/emulator-suite.js b/functions/emulator-suite.js new file mode 100644 index 00000000..87c22b73 --- /dev/null +++ b/functions/emulator-suite.js @@ -0,0 +1,8 @@ +var firebase = require('firebase/app'); +require('firebase/functions'); + +function emulatorSettings() { + // [START functions_emulator_connect] + firebase.functions().useFunctionsEmulator("http://localhost:5001") + // [END functions_emulator_connect] +} diff --git a/functions/package.json b/functions/package.json index 8b0a0846..aecac9f7 100644 --- a/functions/package.json +++ b/functions/package.json @@ -2,15 +2,10 @@ "name": "functions", "version": "1.0.0", "scripts": { - "build": "webpack", "compile": "cp ../tsconfig.json.template ./tsconfig.json && tsc" }, "license": "Apache-2.0", "dependencies": { - "firebase": "^0.800.3" - }, - "devDependencies": { - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12" + "firebase": "^7.17.1" } } diff --git a/functions/src/index.js b/functions/src/index.js deleted file mode 100644 index 8b7043a7..00000000 --- a/functions/src/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./emulator-suite"; diff --git a/lerna.json b/lerna.json index 6ce5fc4a..bf6d962e 100644 --- a/lerna.json +++ b/lerna.json @@ -7,6 +7,7 @@ "firestore", "firestore-next", "functions", + "functions-next", "installations" ], "version": "1.0.0" From ef88e1f31da2e497a774a0e68d0ef31fc735bb10 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:04:02 +0100 Subject: [PATCH 16/22] Add dirty checks --- .github/workflows/test.yml | 15 ++++++++++++--- scripts/checkdirty.sh | 13 +++++++++++++ scripts/test.sh | 11 ----------- 3 files changed, 25 insertions(+), 14 deletions(-) create mode 100755 scripts/checkdirty.sh delete mode 100755 scripts/test.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3452af7e..f2ac9c9e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,16 @@ jobs: path: ~/.npm key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} - - run: npm install + - name: Install dependencies + run: | + npm install + npm run lerna-bootstrap + + - name: Compile snippets + run: npm run lerna-compile + + - name: Check generated snippets + run: | + npm run snippets + ./scripts/checkdirty.sh - - name: "Lint and Test" - run: ./scripts/test.sh diff --git a/scripts/checkdirty.sh b/scripts/checkdirty.sh new file mode 100755 index 00000000..29f5d2eb --- /dev/null +++ b/scripts/checkdirty.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +if [[ $(git diff --stat HEAD) != '' ]]; then + git diff --stat HEAD + echo + echo 'Error: git diff is dirty ... did you forget to run "npm run snippets" after adding snippets?' + exit 1 +else + echo 'Succes: git diff is clean' +fi diff --git a/scripts/test.sh b/scripts/test.sh deleted file mode 100755 index 7527670e..00000000 --- a/scripts/test.sh +++ /dev/null @@ -1,11 +0,0 @@ -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -# 0) Bootstrap -echo "Bootstrapping..." -npm run lerna-bootstrap - -# 1) "Compile" the code -echo "Compiling..." -npm run lerna-compile From fbcf94372362f7281ce2caaec9775c9263170fe0 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:07:57 +0100 Subject: [PATCH 17/22] Fix dirty checking --- scripts/checkdirty.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/checkdirty.sh b/scripts/checkdirty.sh index 29f5d2eb..5d3c8bea 100755 --- a/scripts/checkdirty.sh +++ b/scripts/checkdirty.sh @@ -3,6 +3,8 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +git add . + if [[ $(git diff --stat HEAD) != '' ]]; then git diff --stat HEAD echo From a60a7baf031a18a860a9a77a981eccfc48840c43 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:08:31 +0100 Subject: [PATCH 18/22] Install ts-node --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6f1f8e21..641918cb 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "license": "Apache-2.0", "devDependencies": { "lerna": "^3.22.1", + "ts-node": "^9.0.0", "typescript": "^3.8.3" } } From 43b20a6b8502c8a876d3127d7466c9ef5e86fd31 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:13:27 +0100 Subject: [PATCH 19/22] Fix snippet script --- scripts/separate-snippets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/separate-snippets.ts b/scripts/separate-snippets.ts index 6b4c35a3..c119b9ac 100644 --- a/scripts/separate-snippets.ts +++ b/scripts/separate-snippets.ts @@ -50,7 +50,7 @@ function processSnippet( if (line.match(RE_REQUIRE)) { outputLines.push(line.replace(RE_REQUIRE, `import {$1} from $2`)); } else if (line.match(RE_START_SNIPPET)) { - outputLines.push(line.replace(RE_START_SNIPPET, `[START modular_$1]`)); + outputLines.push(line.replace(RE_START_SNIPPET, `[START ${snippetPrefix}$1]`)); } else if (line.match(RE_END_SNIPPET)) { outputLines.push( line.replace(RE_END_SNIPPET, `[END ${snippetPrefix}$1]`) From d7c681d0dfaa3f40c9e584fe0c512a6d820b5850 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:13:33 +0100 Subject: [PATCH 20/22] Run snippets script --- .../emulator-suite/fs_emulator_connect.js | 19 +++++++ .../test-firestore/add_ada_lovelace.js | 19 +++++++ .../test-firestore/add_alan_turing.js | 22 ++++++++ .../test-firestore/add_document.js | 15 ++++++ .../test-firestore/add_rating_transaction.js | 35 ++++++++++++ .../array_contains_any_filter.js | 11 ++++ .../test-firestore/array_contains_filter.js | 9 ++++ .../test-firestore/chain_filters.js | 11 ++++ .../test-firestore/cities_document_set.js | 10 ++++ .../test-firestore/city_custom_object.js | 32 +++++++++++ .../test-firestore/collection_reference.js | 10 ++++ .../test-firestore/data_types.js | 24 +++++++++ .../test-firestore/delete_collection.js | 48 +++++++++++++++++ .../test-firestore/delete_document.js | 10 ++++ .../test-firestore/detach_listener.js | 18 +++++++ .../test-firestore/disable_network.js | 15 ++++++ .../test-firestore/doc_reference.js | 10 ++++ .../doc_reference_alternative.js | 10 ++++ .../test-firestore/enable_network.js | 14 +++++ .../test-firestore/example_data.js | 31 +++++++++++ .../test-firestore/example_filters.js | 10 ++++ .../test-firestore/filter_and_order.js | 10 ++++ .../fs_collection_group_query.js | 14 +++++ .../fs_collection_group_query_data_setup.js | 53 +++++++++++++++++++ .../test-firestore/fs_setup_cache.js | 12 +++++ .../test-firestore/get_all_users.js | 13 +++++ .../test-firestore/get_custom_object.js | 19 +++++++ .../test-firestore/get_document.js | 18 +++++++ .../test-firestore/get_document_options.js | 21 ++++++++ .../test-firestore/get_multiple.js | 16 ++++++ .../test-firestore/get_multiple_all.js | 14 +++++ .../test-firestore/handle_listen_errors.js | 17 ++++++ .../test-firestore/in_filter.js | 10 ++++ .../test-firestore/in_filter_with_array.js | 10 ++++ .../test-firestore/initialize_persistence.js | 22 ++++++++ .../invalid_filter_and_order.js | 10 ++++ .../test-firestore/invalid_range_filters.js | 10 ++++ .../test-firestore/listen_diffs.js | 23 ++++++++ .../test-firestore/listen_document.js | 12 +++++ .../test-firestore/listen_document_local.js | 13 +++++ .../test-firestore/listen_for_users.js | 16 ++++++ .../test-firestore/listen_multiple.js | 17 ++++++ .../test-firestore/listen_with_metadata.js | 15 ++++++ .../test-firestore/new_document.js | 14 +++++ .../test-firestore/order_and_end.js | 10 ++++ .../test-firestore/order_and_limit.js | 10 ++++ .../test-firestore/order_and_limit_desc.js | 10 ++++ .../test-firestore/order_and_start.js | 10 ++++ .../test-firestore/order_multiple.js | 10 ++++ .../firestore-next/test-firestore/paginate.js | 23 ++++++++ .../server_timestamp_resolution_options.js | 26 +++++++++ .../test-firestore/set_custom_object.js | 12 +++++ .../test-firestore/set_document.js | 15 ++++++ .../test-firestore/set_with_merge.js | 11 ++++ .../test-firestore/simple_queries.js | 13 +++++ .../test-firestore/simple_queries_again.js | 11 ++++ .../test-firestore/start_doc.js | 15 ++++++ .../test-firestore/start_multiple_orderby.js | 19 +++++++ .../test-firestore/subcollection_reference.js | 10 ++++ .../test-firestore/transaction.js | 23 ++++++++ .../test-firestore/transaction_promise.js | 32 +++++++++++ .../test-firestore/update_delete_field.js | 15 ++++++ .../test-firestore/update_document.js | 15 ++++++ .../test-firestore/update_document_array.js | 20 +++++++ .../update_document_increment.js | 15 ++++++ .../test-firestore/update_document_nested.js | 22 ++++++++ .../update_with_server_timestamp.js | 15 ++++++ .../test-firestore/use_from_cache.js | 20 +++++++ .../test-firestore/valid_filter_and_order.js | 10 ++++ .../test-firestore/valid_range_filters.js | 11 ++++ .../test-firestore/write_batch.js | 26 +++++++++ .../get_collection_ratings.js | 11 ++++ .../test-solution-aggregation/sample_doc.js | 12 +++++ .../test-solution-arrays/post_with_array.js | 16 ++++++ .../test-solution-arrays/post_with_map.js | 16 ++++++ .../post_with_map_advanced.js | 16 ++++++ .../test-solution-arrays/query_in_category.js | 14 +++++ .../query_in_category_timestamp.js | 12 +++++ .../query_in_category_timestamp_invalid.js | 12 +++++ .../test-solution-counters/create_counter.js | 24 +++++++++ .../test-solution-counters/get_count.js | 20 +++++++ .../increment_counter.js | 17 ++++++ .../emulator-suite/functions_callable_call.js | 16 ++++++ .../functions_emulator_connect.js | 12 +++++ 84 files changed, 1389 insertions(+) create mode 100644 snippets/firestore-next/emulator-suite/fs_emulator_connect.js create mode 100644 snippets/firestore-next/test-firestore/add_ada_lovelace.js create mode 100644 snippets/firestore-next/test-firestore/add_alan_turing.js create mode 100644 snippets/firestore-next/test-firestore/add_document.js create mode 100644 snippets/firestore-next/test-firestore/add_rating_transaction.js create mode 100644 snippets/firestore-next/test-firestore/array_contains_any_filter.js create mode 100644 snippets/firestore-next/test-firestore/array_contains_filter.js create mode 100644 snippets/firestore-next/test-firestore/chain_filters.js create mode 100644 snippets/firestore-next/test-firestore/cities_document_set.js create mode 100644 snippets/firestore-next/test-firestore/city_custom_object.js create mode 100644 snippets/firestore-next/test-firestore/collection_reference.js create mode 100644 snippets/firestore-next/test-firestore/data_types.js create mode 100644 snippets/firestore-next/test-firestore/delete_collection.js create mode 100644 snippets/firestore-next/test-firestore/delete_document.js create mode 100644 snippets/firestore-next/test-firestore/detach_listener.js create mode 100644 snippets/firestore-next/test-firestore/disable_network.js create mode 100644 snippets/firestore-next/test-firestore/doc_reference.js create mode 100644 snippets/firestore-next/test-firestore/doc_reference_alternative.js create mode 100644 snippets/firestore-next/test-firestore/enable_network.js create mode 100644 snippets/firestore-next/test-firestore/example_data.js create mode 100644 snippets/firestore-next/test-firestore/example_filters.js create mode 100644 snippets/firestore-next/test-firestore/filter_and_order.js create mode 100644 snippets/firestore-next/test-firestore/fs_collection_group_query.js create mode 100644 snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js create mode 100644 snippets/firestore-next/test-firestore/fs_setup_cache.js create mode 100644 snippets/firestore-next/test-firestore/get_all_users.js create mode 100644 snippets/firestore-next/test-firestore/get_custom_object.js create mode 100644 snippets/firestore-next/test-firestore/get_document.js create mode 100644 snippets/firestore-next/test-firestore/get_document_options.js create mode 100644 snippets/firestore-next/test-firestore/get_multiple.js create mode 100644 snippets/firestore-next/test-firestore/get_multiple_all.js create mode 100644 snippets/firestore-next/test-firestore/handle_listen_errors.js create mode 100644 snippets/firestore-next/test-firestore/in_filter.js create mode 100644 snippets/firestore-next/test-firestore/in_filter_with_array.js create mode 100644 snippets/firestore-next/test-firestore/initialize_persistence.js create mode 100644 snippets/firestore-next/test-firestore/invalid_filter_and_order.js create mode 100644 snippets/firestore-next/test-firestore/invalid_range_filters.js create mode 100644 snippets/firestore-next/test-firestore/listen_diffs.js create mode 100644 snippets/firestore-next/test-firestore/listen_document.js create mode 100644 snippets/firestore-next/test-firestore/listen_document_local.js create mode 100644 snippets/firestore-next/test-firestore/listen_for_users.js create mode 100644 snippets/firestore-next/test-firestore/listen_multiple.js create mode 100644 snippets/firestore-next/test-firestore/listen_with_metadata.js create mode 100644 snippets/firestore-next/test-firestore/new_document.js create mode 100644 snippets/firestore-next/test-firestore/order_and_end.js create mode 100644 snippets/firestore-next/test-firestore/order_and_limit.js create mode 100644 snippets/firestore-next/test-firestore/order_and_limit_desc.js create mode 100644 snippets/firestore-next/test-firestore/order_and_start.js create mode 100644 snippets/firestore-next/test-firestore/order_multiple.js create mode 100644 snippets/firestore-next/test-firestore/paginate.js create mode 100644 snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js create mode 100644 snippets/firestore-next/test-firestore/set_custom_object.js create mode 100644 snippets/firestore-next/test-firestore/set_document.js create mode 100644 snippets/firestore-next/test-firestore/set_with_merge.js create mode 100644 snippets/firestore-next/test-firestore/simple_queries.js create mode 100644 snippets/firestore-next/test-firestore/simple_queries_again.js create mode 100644 snippets/firestore-next/test-firestore/start_doc.js create mode 100644 snippets/firestore-next/test-firestore/start_multiple_orderby.js create mode 100644 snippets/firestore-next/test-firestore/subcollection_reference.js create mode 100644 snippets/firestore-next/test-firestore/transaction.js create mode 100644 snippets/firestore-next/test-firestore/transaction_promise.js create mode 100644 snippets/firestore-next/test-firestore/update_delete_field.js create mode 100644 snippets/firestore-next/test-firestore/update_document.js create mode 100644 snippets/firestore-next/test-firestore/update_document_array.js create mode 100644 snippets/firestore-next/test-firestore/update_document_increment.js create mode 100644 snippets/firestore-next/test-firestore/update_document_nested.js create mode 100644 snippets/firestore-next/test-firestore/update_with_server_timestamp.js create mode 100644 snippets/firestore-next/test-firestore/use_from_cache.js create mode 100644 snippets/firestore-next/test-firestore/valid_filter_and_order.js create mode 100644 snippets/firestore-next/test-firestore/valid_range_filters.js create mode 100644 snippets/firestore-next/test-firestore/write_batch.js create mode 100644 snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js create mode 100644 snippets/firestore-next/test-solution-aggregation/sample_doc.js create mode 100644 snippets/firestore-next/test-solution-arrays/post_with_array.js create mode 100644 snippets/firestore-next/test-solution-arrays/post_with_map.js create mode 100644 snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js create mode 100644 snippets/firestore-next/test-solution-arrays/query_in_category.js create mode 100644 snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js create mode 100644 snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js create mode 100644 snippets/firestore-next/test-solution-counters/create_counter.js create mode 100644 snippets/firestore-next/test-solution-counters/get_count.js create mode 100644 snippets/firestore-next/test-solution-counters/increment_counter.js create mode 100644 snippets/functions-next/emulator-suite/functions_callable_call.js create mode 100644 snippets/functions-next/emulator-suite/functions_emulator_connect.js diff --git a/snippets/firestore-next/emulator-suite/fs_emulator_connect.js b/snippets/firestore-next/emulator-suite/fs_emulator_connect.js new file mode 100644 index 00000000..48ef3f16 --- /dev/null +++ b/snippets/firestore-next/emulator-suite/fs_emulator_connect.js @@ -0,0 +1,19 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/emulator-suite/fs_emulator_connect.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_fs_emulator_connect] +import { initializeFirestore } from "firebase/firestore"; + +let settings = {}; +if (location.hostname === "localhost") { + settings = { + host: "localhost:8080", + ssl: false + }; +} + +// firebaseApps previously initialized using initializeApp() +const db = initializeFirestore(firebaseApp, settings); +// [END modular_fs_emulator_connect] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/add_ada_lovelace.js b/snippets/firestore-next/test-firestore/add_ada_lovelace.js new file mode 100644 index 00000000..849b236c --- /dev/null +++ b/snippets/firestore-next/test-firestore/add_ada_lovelace.js @@ -0,0 +1,19 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/add_ada_lovelace.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_add_ada_lovelace] +import { collection, addDoc } from "firebase/firestore"; + +try { + const docRef = await addDoc(collection(db, "users"), { + first: "Ada", + last: "Lovelace", + born: 1815 + }); + console.log("Document written with ID: ", docRef.id); +} catch (e) { + console.error("Error adding document: ", e); +} +// [END modular_add_ada_lovelace] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/add_alan_turing.js b/snippets/firestore-next/test-firestore/add_alan_turing.js new file mode 100644 index 00000000..f71a2ea0 --- /dev/null +++ b/snippets/firestore-next/test-firestore/add_alan_turing.js @@ -0,0 +1,22 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/add_alan_turing.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_add_alan_turing] +// Add a second document with a generated ID. +import { addDoc, collection } from "firebase/firestore"; + +try { + const docRef = await addDoc(collection(db, "users"), { + first: "Alan", + middle: "Mathison", + last: "Turing", + born: 1912 + }); + + console.log("Document written with ID: ", docRef.id); +} catch (e) { + console.error("Error adding document: ", e); +} +// [END modular_add_alan_turing] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/add_document.js b/snippets/firestore-next/test-firestore/add_document.js new file mode 100644 index 00000000..0c5eb640 --- /dev/null +++ b/snippets/firestore-next/test-firestore/add_document.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/add_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_add_document] +import { collection, addDoc } from "firebase/firestore"; + +// Add a new document with a generated id. +const docRef = await addDoc(collection(db, "cities"), { + name: "Tokyo", + country: "Japan" +}); +console.log("Document written with ID: ", docRef.id); +// [END modular_add_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/add_rating_transaction.js b/snippets/firestore-next/test-firestore/add_rating_transaction.js new file mode 100644 index 00000000..2c2b931a --- /dev/null +++ b/snippets/firestore-next/test-firestore/add_rating_transaction.js @@ -0,0 +1,35 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/add_rating_transaction.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_add_rating_transaction] +import { collection, doc, runTransaction} from "firebase/firestore"; + +async function addRating(restaurantRef, rating) { + // Create a reference for a new rating, for use inside the transaction + const ratingRef = doc(collection(restaurantRef, 'ratings')); + + // In a transaction, add the new rating and update the aggregate totals + await runTransaction(db, async (transaction) => { + const res = await transaction.get(restaurantRef); + if (!res.exists()) { + throw "Document does not exist!"; + } + + // Compute new number of ratings + const newNumRatings = res.data().numRatings + 1; + + // Compute new average rating + const oldRatingTotal = res.data().avgRating * res.data().numRatings; + const newAvgRating = (oldRatingTotal + rating) / newNumRatings; + + // Commit to Firestore + transaction.update(restaurantRef, { + numRatings: newNumRatings, + avgRating: newAvgRating + }); + transaction.set(ratingRef, { rating: rating }); + }); +} +// [END modular_add_rating_transaction] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/array_contains_any_filter.js b/snippets/firestore-next/test-firestore/array_contains_any_filter.js new file mode 100644 index 00000000..66049452 --- /dev/null +++ b/snippets/firestore-next/test-firestore/array_contains_any_filter.js @@ -0,0 +1,11 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/array_contains_any_filter.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_array_contains_any_filter] +import { query, where } from "firebase/firestore"; + +const q = query(citiesRef, + where('regions', 'array-contains-any', ['west_coast', 'east_coast'])); +// [END modular_array_contains_any_filter] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/array_contains_filter.js b/snippets/firestore-next/test-firestore/array_contains_filter.js new file mode 100644 index 00000000..05f5a467 --- /dev/null +++ b/snippets/firestore-next/test-firestore/array_contains_filter.js @@ -0,0 +1,9 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/array_contains_filter.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_array_contains_filter] +import { query, where } from "firebase/firestore"; +const q = query(citiesRef, where("regions", "array-contains", "west_coast")); +// [END modular_array_contains_filter] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/chain_filters.js b/snippets/firestore-next/test-firestore/chain_filters.js new file mode 100644 index 00000000..cd956507 --- /dev/null +++ b/snippets/firestore-next/test-firestore/chain_filters.js @@ -0,0 +1,11 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/chain_filters.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_chain_filters] +import { query, where } from "firebase/firestore"; + +const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); +const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000)); +// [END modular_chain_filters] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/cities_document_set.js b/snippets/firestore-next/test-firestore/cities_document_set.js new file mode 100644 index 00000000..c3a42e82 --- /dev/null +++ b/snippets/firestore-next/test-firestore/cities_document_set.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/cities_document_set.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_cities_document_set] +import { collection, doc, setDoc } from "firebase/firestore"; + +await setDoc(doc(collection(db, "cities"), "new-city-id"), data); +// [END modular_cities_document_set] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/city_custom_object.js b/snippets/firestore-next/test-firestore/city_custom_object.js new file mode 100644 index 00000000..d4d0ca49 --- /dev/null +++ b/snippets/firestore-next/test-firestore/city_custom_object.js @@ -0,0 +1,32 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/city_custom_object.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_city_custom_object] +class City { + constructor (name, state, country ) { + this.name = name; + this.state = state; + this.country = country; + } + toString() { + return this.name + ', ' + this.state + ', ' + this.country; + } +} + +// Firestore data converter +var cityConverter = { + toFirestore: function(city) { + return { + name: city.name, + state: city.state, + country: city.country + } + }, + fromFirestore: function(snapshot, options){ + const data = snapshot.data(options); + return new City(data.name, data.state, data.country) + } +} +// [END modular_city_custom_object] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/collection_reference.js b/snippets/firestore-next/test-firestore/collection_reference.js new file mode 100644 index 00000000..4505ab12 --- /dev/null +++ b/snippets/firestore-next/test-firestore/collection_reference.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/collection_reference.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_collection_reference] +import { collection } from "firebase/firestore"; + +const usersCollectionRef = collection(db, 'users'); +// [END modular_collection_reference] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/data_types.js b/snippets/firestore-next/test-firestore/data_types.js new file mode 100644 index 00000000..1c4b56c4 --- /dev/null +++ b/snippets/firestore-next/test-firestore/data_types.js @@ -0,0 +1,24 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/data_types.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_data_types] +import { doc, collection, setDoc, Timestamp } from "firebase/firestore"; + +const docData = { + stringExample: "Hello world!", + booleanExample: true, + numberExample: 3.14159265, + dateExample: Timestamp.fromDate(new Date("December 10, 1815")), + arrayExample: [5, true, "hello"], + nullExample: null, + objectExample: { + a: 5, + b: { + nested: "foo" + } + } +}; +await setDoc(doc(collection(db, "data"), "one"), docData); +// [END modular_data_types] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/delete_collection.js b/snippets/firestore-next/test-firestore/delete_collection.js new file mode 100644 index 00000000..870e2fa2 --- /dev/null +++ b/snippets/firestore-next/test-firestore/delete_collection.js @@ -0,0 +1,48 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/delete_collection.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_delete_collection] +/** + * Delete a collection, in batches of batchSize. Note that this does + * not recursively delete subcollections of documents in the collection + */ +import { collection, query, orderBy, limit, getDocs, writeBatch } from "firebase/firestore"; + +function deleteCollection(db, collectionRef, batchSize) { + const q = query(collectionRef, orderBy('__name__'), limit(batchSize)) + + return new Promise(function(resolve) { + deleteQueryBatch(db, q, batchSize, resolve); + }); +} + +async function deleteQueryBatch(db, query, batchSize, resolve) { + const snapshot = await getDocs(query); + + // When there are no documents left, we are done + let numDeleted = 0; + if (snapshot.size > 0) { + // Delete documents in a batch + const batch = writeBatch(db); + snapshot.docs.forEach((doc) => { + batch.delete(doc.ref); + }); + + await batch.commit(); + numDeleted = snapshot.size; + } + + if (numDeleted < batchSize) { + resolve(); + return; + } + + // Recurse on the next process tick, to avoid + // exploding the stack. + setTimeout(() => { + deleteQueryBatch(db, query, batchSize, resolve); + }, 0); +} +// [END modular_delete_collection] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/delete_document.js b/snippets/firestore-next/test-firestore/delete_document.js new file mode 100644 index 00000000..01700abc --- /dev/null +++ b/snippets/firestore-next/test-firestore/delete_document.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/delete_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_delete_document] +import { collection, doc, deleteDoc } from "firebase/firestore"; + +await deleteDoc(doc(collection(db, "cities"), "DC")); +// [END modular_delete_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/detach_listener.js b/snippets/firestore-next/test-firestore/detach_listener.js new file mode 100644 index 00000000..4de580f6 --- /dev/null +++ b/snippets/firestore-next/test-firestore/detach_listener.js @@ -0,0 +1,18 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/detach_listener.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_detach_listener] +import { collection, onSnapshot } from "firebase/firestore"; + +const unsubscribe = onSnapshot(collection(db, "cities"), () => { + // Respond to data + // ... +}); + +// Later ... + +// Stop listening to changes +unsubscribe(); +// [END modular_detach_listener] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/disable_network.js b/snippets/firestore-next/test-firestore/disable_network.js new file mode 100644 index 00000000..d2ce1151 --- /dev/null +++ b/snippets/firestore-next/test-firestore/disable_network.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/disable_network.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_disable_network] +import { disableNetwork } from "firebase/firestore"; + +await disableNetwork(db); +console.log("Network disabled!"); +// Do offline actions +// [START_EXCLUDE] +console.log("Network disabled!"); +// [END_EXCLUDE] +// [END modular_disable_network] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/doc_reference.js b/snippets/firestore-next/test-firestore/doc_reference.js new file mode 100644 index 00000000..641f647e --- /dev/null +++ b/snippets/firestore-next/test-firestore/doc_reference.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/doc_reference.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_doc_reference] +import { collection, doc } from "firebase/firestore"; + +const alovelaceDocumentRef = doc(collection(db, 'users'), 'alovelace'); +// [END modular_doc_reference] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/doc_reference_alternative.js b/snippets/firestore-next/test-firestore/doc_reference_alternative.js new file mode 100644 index 00000000..a221a21a --- /dev/null +++ b/snippets/firestore-next/test-firestore/doc_reference_alternative.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/doc_reference_alternative.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_doc_reference_alternative] +import { doc } from "firebase/firestore"; + +const alovelaceDocumentRef = doc(db, 'users/alovelace'); +// [END modular_doc_reference_alternative] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/enable_network.js b/snippets/firestore-next/test-firestore/enable_network.js new file mode 100644 index 00000000..002c51bc --- /dev/null +++ b/snippets/firestore-next/test-firestore/enable_network.js @@ -0,0 +1,14 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/enable_network.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_enable_network] +import { enableNetwork } from "firebase/firestore"; + +await enableNetwork(db) +// Do online actions +// [START_EXCLUDE] +console.log("Network enabled!"); +// [END_EXCLUDE] +// [END modular_enable_network] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/example_data.js b/snippets/firestore-next/test-firestore/example_data.js new file mode 100644 index 00000000..ff1a2573 --- /dev/null +++ b/snippets/firestore-next/test-firestore/example_data.js @@ -0,0 +1,31 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/example_data.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_example_data] +import { collection, doc, setDoc } from "firebase/firestore"; + +const citiesRef = collection(db, "cities"); + +await setDoc(doc(citiesRef, "SF"), { + name: "San Francisco", state: "CA", country: "USA", + capital: false, population: 860000, + regions: ["west_coast", "norcal"] }); +await setDoc(doc(citiesRef, "LA"), { + name: "Los Angeles", state: "CA", country: "USA", + capital: false, population: 3900000, + regions: ["west_coast", "socal"] }); +await setDoc(doc(citiesRef, "DC"), { + name: "Washington, D.C.", state: null, country: "USA", + capital: true, population: 680000, + regions: ["east_coast"] }); +await setDoc(doc(citiesRef, "TOK"), { + name: "Tokyo", state: null, country: "Japan", + capital: true, population: 9000000, + regions: ["kanto", "honshu"] }); +await setDoc(doc(citiesRef, "BJ"), { + name: "Beijing", state: null, country: "China", + capital: true, population: 21500000, + regions: ["jingjinji", "hebei"] }); +// [END modular_example_data] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/example_filters.js b/snippets/firestore-next/test-firestore/example_filters.js new file mode 100644 index 00000000..622528ea --- /dev/null +++ b/snippets/firestore-next/test-firestore/example_filters.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/example_filters.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_example_filters] +const q1 = query(citiesRef, where("state", "==", "CA")); +const q2 = query(citiesRef, where("population", "<", 100000)); +const q3 = query(citiesRef, where("name", ">=", "San Francisco")); +// [END modular_example_filters] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/filter_and_order.js b/snippets/firestore-next/test-firestore/filter_and_order.js new file mode 100644 index 00000000..3b65ba0f --- /dev/null +++ b/snippets/firestore-next/test-firestore/filter_and_order.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/filter_and_order.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_filter_and_order] +import { query, where, orderBy, limit } from "firebase/firestore"; + +const q = query(citiesRef, where("population", ">", 100000), orderBy("population"), limit(2)); +// [END modular_filter_and_order] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/fs_collection_group_query.js b/snippets/firestore-next/test-firestore/fs_collection_group_query.js new file mode 100644 index 00000000..8af906b1 --- /dev/null +++ b/snippets/firestore-next/test-firestore/fs_collection_group_query.js @@ -0,0 +1,14 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/fs_collection_group_query.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_fs_collection_group_query] +import { collectionGroup, query, where, getDocs } from "firebase/firestore"; + +const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum')); +const querySnapshot = await getDocs(museums); +querySnapshot.forEach((doc) => { + console.log(doc.id, ' => ', doc.data()); +}); +// [END modular_fs_collection_group_query] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js b/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js new file mode 100644 index 00000000..6082bcea --- /dev/null +++ b/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js @@ -0,0 +1,53 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_fs_collection_group_query_data_setup] +import { collection, doc, setDoc } from "firebase/firestore"; + +const citiesRef = collection(db, 'cities'); + +await Promise.all([ + setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { + name: 'Golden Gate Bridge', + type: 'bridge' + }), + setDoc(doc(collection(doc(citiesRef, 'SF'), 'landmarks')), { + name: 'Legion of Honor', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { + name: 'Griffith Park', + type: 'park' + }), + setDoc(doc(collection(doc(citiesRef, 'LA'), 'landmarks')), { + name: 'The Getty', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { + name: 'Lincoln Memorial', + type: 'memorial' + }), + setDoc(doc(collection(doc(citiesRef, 'DC'), 'landmarks')), { + name: 'National Air and Space Museum', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { + name: 'Ueno Park', + type: 'park' + }), + setDoc(doc(collection(doc(citiesRef, 'TOK'), 'landmarks')), { + name: 'National Museum of Nature and Science', + type: 'museum' + }), + setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { + name: 'Jingshan Park', + type: 'park' + }), + setDoc(doc(collection(doc(citiesRef, 'BJ'), 'landmarks')), { + name: 'Beijing Ancient Observatory', + type: 'museum' + }) +]); +// [END modular_fs_collection_group_query_data_setup] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/fs_setup_cache.js b/snippets/firestore-next/test-firestore/fs_setup_cache.js new file mode 100644 index 00000000..7c209d8d --- /dev/null +++ b/snippets/firestore-next/test-firestore/fs_setup_cache.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/fs_setup_cache.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_fs_setup_cache] +import { initializeFirestore, CACHE_SIZE_UNLIMITED } from "firebase/firestore"; + +const firestoreDb = initializeFirestore(app, { + cacheSizeBytes: CACHE_SIZE_UNLIMITED +}); +// [END modular_fs_setup_cache] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/get_all_users.js b/snippets/firestore-next/test-firestore/get_all_users.js new file mode 100644 index 00000000..9caba862 --- /dev/null +++ b/snippets/firestore-next/test-firestore/get_all_users.js @@ -0,0 +1,13 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/get_all_users.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_all_users] +import { collection, getDocs } from "firebase/firestore"; + +const querySnapshot = await getDocs(collection(db, "users")); +querySnapshot.forEach((doc) => { + console.log(`${doc.id} => ${doc.data()}`); +}); +// [END modular_get_all_users] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/get_custom_object.js b/snippets/firestore-next/test-firestore/get_custom_object.js new file mode 100644 index 00000000..dfd1d79d --- /dev/null +++ b/snippets/firestore-next/test-firestore/get_custom_object.js @@ -0,0 +1,19 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/get_custom_object.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_custom_object] +import { doc, collection, getDoc} from "firebase/firestore"; + +const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); +const docSnap = await getDoc(ref); +if (docSnap.exists()) { + // Convert to City object + const city = docSnap.data(); + // Use a City instance method + console.log(city.toString()); +} else { + console.log("No such document!") +} +// [END modular_get_custom_object] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/get_document.js b/snippets/firestore-next/test-firestore/get_document.js new file mode 100644 index 00000000..dd421654 --- /dev/null +++ b/snippets/firestore-next/test-firestore/get_document.js @@ -0,0 +1,18 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/get_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_document] +import { collection, doc, getDoc } from "firebase/firestore"; + +const docRef = doc(collection(db, "cities"), "SF"); +const docSnap = await getDoc(docRef); + +if (docSnap.exists()) { + console.log("Document data:", docSnap.data()); +} else { + // doc.data() will be undefined in this case + console.log("No such document!"); +} +// [END modular_get_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/get_document_options.js b/snippets/firestore-next/test-firestore/get_document_options.js new file mode 100644 index 00000000..58c5c862 --- /dev/null +++ b/snippets/firestore-next/test-firestore/get_document_options.js @@ -0,0 +1,21 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/get_document_options.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_document_options] +import { collection, doc, getDocFromCache } from "firebase/firestore"; + +const docRef = doc(collection(db, "cities"), "SF"); + +// Get a document, forcing the SDK to fetch from the offline cache. +try { + const doc = await getDocFromCache(docRef); + + // Document was found in the cache. If no cached document exists, + // an error will be returned to the 'catch' block below. + console.log("Cached document data:", doc.data()); +} catch (e) { + console.log("Error getting cached document:", e); +} +// [END modular_get_document_options] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/get_multiple.js b/snippets/firestore-next/test-firestore/get_multiple.js new file mode 100644 index 00000000..78d5261c --- /dev/null +++ b/snippets/firestore-next/test-firestore/get_multiple.js @@ -0,0 +1,16 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/get_multiple.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_multiple] +import { collection, query, where, getDocs } from "firebase/firestore"; + +const q = query(collection(db, "cities"), where("capital", "==", true)); + +const querySnapshot = await getDocs(q); +querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); +}); +// [END modular_get_multiple] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/get_multiple_all.js b/snippets/firestore-next/test-firestore/get_multiple_all.js new file mode 100644 index 00000000..2c1ad434 --- /dev/null +++ b/snippets/firestore-next/test-firestore/get_multiple_all.js @@ -0,0 +1,14 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/get_multiple_all.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_multiple_all] +import { collection, getDocs } from "firebase/firestore"; + +const querySnapshot = await getDocs(collection(db, "cities")); +querySnapshot.forEach((doc) => { + // doc.data() is never undefined for query doc snapshots + console.log(doc.id, " => ", doc.data()); +}); +// [END modular_get_multiple_all] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/handle_listen_errors.js b/snippets/firestore-next/test-firestore/handle_listen_errors.js new file mode 100644 index 00000000..469740c0 --- /dev/null +++ b/snippets/firestore-next/test-firestore/handle_listen_errors.js @@ -0,0 +1,17 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/handle_listen_errors.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_handle_listen_errors] +import { collection, onSnapshot } from "firebase/firestore"; + +const unsubscribe = onSnapshot( + collection(db, "cities"), + (snapshot) => { + // ... + }, + (error) => { + // ... + }); +// [END modular_handle_listen_errors] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/in_filter.js b/snippets/firestore-next/test-firestore/in_filter.js new file mode 100644 index 00000000..137ae040 --- /dev/null +++ b/snippets/firestore-next/test-firestore/in_filter.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/in_filter.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_in_filter] +import { query, where } from "firebase/firestore"; + +const q = query(citiesRef, where('country', 'in', ['USA', 'Japan'])); +// [END modular_in_filter] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/in_filter_with_array.js b/snippets/firestore-next/test-firestore/in_filter_with_array.js new file mode 100644 index 00000000..1b9b7cec --- /dev/null +++ b/snippets/firestore-next/test-firestore/in_filter_with_array.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/in_filter_with_array.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_in_filter_with_array] +import { query, where } from "firebase/firestore"; + +const q = query(citiesRef, where('regions', 'in', [['west_coast', 'east_coast']])); +// [END modular_in_filter_with_array] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/initialize_persistence.js b/snippets/firestore-next/test-firestore/initialize_persistence.js new file mode 100644 index 00000000..1dda0c5e --- /dev/null +++ b/snippets/firestore-next/test-firestore/initialize_persistence.js @@ -0,0 +1,22 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/initialize_persistence.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_initialize_persistence] +import { enableIndexedDbPersistence } from "firebase/firestore"; + +enableIndexedDbPersistence(db) + .catch((err) => { + if (err.code == 'failed-precondition') { + // Multiple tabs open, persistence can only be enabled + // in one tab at a a time. + // ... + } else if (err.code == 'unimplemented') { + // The current browser does not support all of the + // features required to enable persistence + // ... + } + }); +// Subsequent queries will use persistence, if it was enabled successfully +// [END modular_initialize_persistence] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/invalid_filter_and_order.js b/snippets/firestore-next/test-firestore/invalid_filter_and_order.js new file mode 100644 index 00000000..afc31fd2 --- /dev/null +++ b/snippets/firestore-next/test-firestore/invalid_filter_and_order.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/invalid_filter_and_order.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_invalid_filter_and_order] +import { query, where, orderBy } from "firebase/firestore"; + +const q = query(citiesRef, where("population", ">", 100000), orderBy("country")); +// [END modular_invalid_filter_and_order] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/invalid_range_filters.js b/snippets/firestore-next/test-firestore/invalid_range_filters.js new file mode 100644 index 00000000..d5a693d3 --- /dev/null +++ b/snippets/firestore-next/test-firestore/invalid_range_filters.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/invalid_range_filters.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_invalid_range_filters] +import { query, where } from "firebase/firestore"; + +const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000)); +// [END modular_invalid_range_filters] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/listen_diffs.js b/snippets/firestore-next/test-firestore/listen_diffs.js new file mode 100644 index 00000000..299ffc25 --- /dev/null +++ b/snippets/firestore-next/test-firestore/listen_diffs.js @@ -0,0 +1,23 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/listen_diffs.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_listen_diffs] +import { collection, query, where, onSnapshot } from "firebase/firestore"; + +const q = query(collection(db, "cities"), where("state", "==", "CA")); +const unsubscribe = onSnapshot(q, (snapshot) => { + snapshot.docChanges().forEach((change) => { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + if (change.type === "modified") { + console.log("Modified city: ", change.doc.data()); + } + if (change.type === "removed") { + console.log("Removed city: ", change.doc.data()); + } + }); +}); +// [END modular_listen_diffs] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/listen_document.js b/snippets/firestore-next/test-firestore/listen_document.js new file mode 100644 index 00000000..d21ad645 --- /dev/null +++ b/snippets/firestore-next/test-firestore/listen_document.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/listen_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_listen_document] +import { collection, doc, onSnapshot } from "firebase/firestore"; + +const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { + console.log("Current data: ", doc.data()); +}); +// [END modular_listen_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/listen_document_local.js b/snippets/firestore-next/test-firestore/listen_document_local.js new file mode 100644 index 00000000..c6da4542 --- /dev/null +++ b/snippets/firestore-next/test-firestore/listen_document_local.js @@ -0,0 +1,13 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/listen_document_local.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_listen_document_local] +import { collection, doc, onSnapshot } from "firebase/firestore"; + +const unsub = onSnapshot(doc(collection(db, "cities"), "SF"), (doc) => { + const source = doc.metadata.hasPendingWrites ? "Local" : "Server"; + console.log(source, " data: ", doc.data()); +}); +// [END modular_listen_document_local] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/listen_for_users.js b/snippets/firestore-next/test-firestore/listen_for_users.js new file mode 100644 index 00000000..18060df4 --- /dev/null +++ b/snippets/firestore-next/test-firestore/listen_for_users.js @@ -0,0 +1,16 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/listen_for_users.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_listen_for_users] +import { collection, where, query, onSnapshot } from "firebase/firestore"; + +const q = query(collection(db, "users"), where("born", "<", 1900)); +const unsubscribe = onSnapshot(q, (snapshot) => { + console.log("Current users born before 1900:"); + snapshot.forEach(function (userSnapshot) { + console.log(userSnapshot.data()) + }); +}); +// [END modular_listen_for_users] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/listen_multiple.js b/snippets/firestore-next/test-firestore/listen_multiple.js new file mode 100644 index 00000000..258151ad --- /dev/null +++ b/snippets/firestore-next/test-firestore/listen_multiple.js @@ -0,0 +1,17 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/listen_multiple.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_listen_multiple] +import { collection, query, where, onSnapshot } from "firebase/firestore"; + +const q = query(collection(db, "cities"), where("state", "==", "CA")); +const unsubscribe = onSnapshot(q, (querySnapshot) => { + const cities = []; + querySnapshot.forEach((doc) => { + cities.push(doc.data().name); + }); + console.log("Current cities in CA: ", cities.join(", ")); +}); +// [END modular_listen_multiple] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/listen_with_metadata.js b/snippets/firestore-next/test-firestore/listen_with_metadata.js new file mode 100644 index 00000000..b555d6d8 --- /dev/null +++ b/snippets/firestore-next/test-firestore/listen_with_metadata.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/listen_with_metadata.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_listen_with_metadata] +import { collection, doc, onSnapshot } from "firebase/firestore"; + +const unsub = onSnapshot( + doc(collection(db, "cities"), "SF"), + { includeMetadataChanges: true }, + (doc) => { + // ... + }); +// [END modular_listen_with_metadata] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/new_document.js b/snippets/firestore-next/test-firestore/new_document.js new file mode 100644 index 00000000..c874e962 --- /dev/null +++ b/snippets/firestore-next/test-firestore/new_document.js @@ -0,0 +1,14 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/new_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_new_document] +import { collection, doc, setDoc } from "firebase/firestore"; + +// Add a new document with a generated id +const newCityRef = doc(collection(db, "cities")); + +// later... +await setDoc(newCityRef, data); +// [END modular_new_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/order_and_end.js b/snippets/firestore-next/test-firestore/order_and_end.js new file mode 100644 index 00000000..3dbda981 --- /dev/null +++ b/snippets/firestore-next/test-firestore/order_and_end.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/order_and_end.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_order_and_end] +import { query, orderBy, endAt } from "firebase/firestore"; + +const q = query(citiesRef, orderBy("population"), endAt(1000000)); +// [END modular_order_and_end] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/order_and_limit.js b/snippets/firestore-next/test-firestore/order_and_limit.js new file mode 100644 index 00000000..57f46094 --- /dev/null +++ b/snippets/firestore-next/test-firestore/order_and_limit.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/order_and_limit.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_order_and_limit] +import { query, orderBy, limit } from "firebase/firestore"; + +const q = query(citiesRef, orderBy("name"), limit(3)); +// [END modular_order_and_limit] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/order_and_limit_desc.js b/snippets/firestore-next/test-firestore/order_and_limit_desc.js new file mode 100644 index 00000000..89e3eab1 --- /dev/null +++ b/snippets/firestore-next/test-firestore/order_and_limit_desc.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/order_and_limit_desc.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_order_and_limit_desc] +import { query, orderBy, limit } from "firebase/firestore"; + +const q = query(citiesRef, orderBy("name", "desc"), limit(3)); +// [END modular_order_and_limit_desc] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/order_and_start.js b/snippets/firestore-next/test-firestore/order_and_start.js new file mode 100644 index 00000000..78013ca8 --- /dev/null +++ b/snippets/firestore-next/test-firestore/order_and_start.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/order_and_start.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_order_and_start] +import { query, orderBy, startAt } from "firebase/firestore"; + +const q = query(citiesRef, orderBy("population"), startAt(1000000)); +// [END modular_order_and_start] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/order_multiple.js b/snippets/firestore-next/test-firestore/order_multiple.js new file mode 100644 index 00000000..064c206f --- /dev/null +++ b/snippets/firestore-next/test-firestore/order_multiple.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/order_multiple.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_order_multiple] +import { query, orderBy } from "firebase/firestore"; + +const q = query(citiesRef, orderBy("state"), orderBy("population", "desc")); +// [END modular_order_multiple] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/paginate.js b/snippets/firestore-next/test-firestore/paginate.js new file mode 100644 index 00000000..d2a0effd --- /dev/null +++ b/snippets/firestore-next/test-firestore/paginate.js @@ -0,0 +1,23 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/paginate.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_paginate] +import { collection, query, orderBy, startAfter, limit, getDocs } from "firebase/firestore"; + +// Query the first page of docs +const first = query(collection(db, "cities"), orderBy("population"), limit(25)); +const documentSnapshots = await getDocs(first); + +// Get the last visible document +const lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; +console.log("last", lastVisible); + +// Construct a new query starting at this document, +// get the next 25 cities. +const next = query(collection(db, "cities"), + orderBy("population"), + startAfter(lastVisible), + limit(25)); +// [END modular_paginate] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js b/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js new file mode 100644 index 00000000..a71e9954 --- /dev/null +++ b/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js @@ -0,0 +1,26 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_server_timestamp_resolution_options] +import { collection, doc, updateDoc, serverTimestamp, onSnapshot } from "firebase/firestore"; +// Perform an update followed by an immediate read without +// waiting for the update to complete. Due to the snapshot +// options we will get two results: one with an estimate +// timestamp and one with the resolved server timestamp. +const docRef = doc(collection(db, 'objects'), 'some-id'); +updateDoc(docRef, { + timestamp: serverTimestamp() +}); + +onSnapshot(docRef, (snapshot) => { + const data = snapshot.data({ + // Options: 'estimate', 'previous', or 'none' + serverTimestamps: "estimate" + }); + console.log( + 'Timestamp: ' + data.timestamp + + ', pending: ' + snapshot.metadata.hasPendingWrites); +}); +// [END modular_server_timestamp_resolution_options] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/set_custom_object.js b/snippets/firestore-next/test-firestore/set_custom_object.js new file mode 100644 index 00000000..6d6c06a3 --- /dev/null +++ b/snippets/firestore-next/test-firestore/set_custom_object.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/set_custom_object.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_set_custom_object] +import { doc, collection, setDoc } from "firebase/firestore"; + +// Set with cityConverter +const ref = doc(collection(db, "cities"), "LA").withConverter(cityConverter); +await setDoc(ref, new City("Los Angeles", "CA", "USA")); +// [END modular_set_custom_object] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/set_document.js b/snippets/firestore-next/test-firestore/set_document.js new file mode 100644 index 00000000..548fb59d --- /dev/null +++ b/snippets/firestore-next/test-firestore/set_document.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/set_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_set_document] +import { doc, collection, setDoc } from "firebase/firestore"; + +// Add a new document in collection "cities" +await setDoc(doc(collection(db, "cities"), "LA"), { + name: "Los Angeles", + state: "CA", + country: "USA" +}); +// [END modular_set_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/set_with_merge.js b/snippets/firestore-next/test-firestore/set_with_merge.js new file mode 100644 index 00000000..b2e17e19 --- /dev/null +++ b/snippets/firestore-next/test-firestore/set_with_merge.js @@ -0,0 +1,11 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/set_with_merge.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_set_with_merge] +import { doc, collection, setDoc } from "firebase/firestore"; + +const cityRef = doc(collection(db, 'cities'), 'BJ'); +setDoc(cityRef, { capital: true }, { merge: true }); +// [END modular_set_with_merge] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/simple_queries.js b/snippets/firestore-next/test-firestore/simple_queries.js new file mode 100644 index 00000000..6ea0b924 --- /dev/null +++ b/snippets/firestore-next/test-firestore/simple_queries.js @@ -0,0 +1,13 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/simple_queries.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_simple_queries] +// Create a reference to the cities collection +import { collection, query, where } from "firebase/firestore"; +const citiesRef = collection(db, "cities"); + +// Create a query against the collection. +const q = query(citiesRef, where("state", "==", "CA")); +// [END modular_simple_queries] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/simple_queries_again.js b/snippets/firestore-next/test-firestore/simple_queries_again.js new file mode 100644 index 00000000..9ea640c1 --- /dev/null +++ b/snippets/firestore-next/test-firestore/simple_queries_again.js @@ -0,0 +1,11 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/simple_queries_again.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_simple_queries_again] +import { collection, query, where } from "firebase/firestore"; +const citiesRef = collection(db, "cities"); + +const q = query(citiesRef, where("capital", "==", true)); +// [END modular_simple_queries_again] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/start_doc.js b/snippets/firestore-next/test-firestore/start_doc.js new file mode 100644 index 00000000..680041bf --- /dev/null +++ b/snippets/firestore-next/test-firestore/start_doc.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/start_doc.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_start_doc] +import { collection, doc, getDoc, query, orderBy, startAt } from "firebase/firestore"; +const citiesRef = collection(db, "cities"); + +const docSnap = await getDoc(doc(citiesRef, "SF")); + +// Get all cities with a population bigger than San Francisco +const biggerThanSf = query(citiesRef, orderBy("popuation"), startAt(docSnap)); +// ... +// [END modular_start_doc] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/start_multiple_orderby.js b/snippets/firestore-next/test-firestore/start_multiple_orderby.js new file mode 100644 index 00000000..66773e23 --- /dev/null +++ b/snippets/firestore-next/test-firestore/start_multiple_orderby.js @@ -0,0 +1,19 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/start_multiple_orderby.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_start_multiple_orderby] +// Will return all Springfields +import { collection, query, orderBy, startAt } from "firebase/firestore"; +const q1 = query(collection(db, "cities"), + orderBy("name"), + orderBy("state"), + startAt("Springfield")); + +// Will return "Springfield, Missouri" and "Springfield, Wisconsin" +const q2 = query(collection(db, "cities"), + orderBy("name"), + orderBy("state"), + startAt("Springfield", "Missouri")); +// [END modular_start_multiple_orderby] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/subcollection_reference.js b/snippets/firestore-next/test-firestore/subcollection_reference.js new file mode 100644 index 00000000..b7eef5bb --- /dev/null +++ b/snippets/firestore-next/test-firestore/subcollection_reference.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/subcollection_reference.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_subcollection_reference] +import { doc, collection } from "firebase/firestore"; + +const messageRef = doc(collection(doc(collection(db, "rooms"), "roomA"), "messages"), "message1"); +// [END modular_subcollection_reference] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/transaction.js b/snippets/firestore-next/test-firestore/transaction.js new file mode 100644 index 00000000..3c5201b1 --- /dev/null +++ b/snippets/firestore-next/test-firestore/transaction.js @@ -0,0 +1,23 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/transaction.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_transaction] +import { runTransaction } from "firebase/firestore"; + +try { + await runTransaction(db, async (transaction) => { + const sfDoc = await transaction.get(sfDocRef); + if (!sfDoc.exists()) { + throw "Document does not exist!"; + } + + const newPopulation = sfDoc.data().population + 1; + transaction.update(sfDocRef, { population: newPopulation }); + }); + console.log("Transaction successfully committed!"); +} catch (e) { + console.log("Transaction failed: ", e); +} +// [END modular_transaction] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/transaction_promise.js b/snippets/firestore-next/test-firestore/transaction_promise.js new file mode 100644 index 00000000..2f92799d --- /dev/null +++ b/snippets/firestore-next/test-firestore/transaction_promise.js @@ -0,0 +1,32 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/transaction_promise.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_transaction_promise] +import { collection, doc, runTransaction } from "firebase/firestore"; + +// Create a reference to the SF doc. +const sfDocRef = doc(collection(db, "cities"), "SF"); + +try { + const newPopulation = await runTransaction(db, async (transaction) => { + const sfDoc = await transaction.get(sfDocRef); + if (!sfDoc.exists()) { + throw "Document does not exist!"; + } + + const newPop = sfDoc.data().population + 1; + if (newPop <= 1000000) { + transaction.update(sfDocRef, { population: newPop }); + } else { + return Promise.reject("Sorry! Population is too big"); + } + }); + + console.log("Population increased to ", newPopulation); +} catch (e) { + // This will be a "population is too big" error. + console.error(e); +} +// [END modular_transaction_promise] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/update_delete_field.js b/snippets/firestore-next/test-firestore/update_delete_field.js new file mode 100644 index 00000000..d490909b --- /dev/null +++ b/snippets/firestore-next/test-firestore/update_delete_field.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/update_delete_field.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_update_delete_field] +import { doc, collection, updateDoc, deleteField } from "firebase/firestore"; + +const cityRef = doc(collection(db, 'cities'), 'BJ'); + +// Remove the 'capital' field from the document +await updateDoc(cityRef, { + capital: deleteField() +}); +// [END modular_update_delete_field] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/update_document.js b/snippets/firestore-next/test-firestore/update_document.js new file mode 100644 index 00000000..64824b65 --- /dev/null +++ b/snippets/firestore-next/test-firestore/update_document.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/update_document.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_update_document] +import { collection, doc, updateDoc } from "firebase/firestore"; + +const washingtonRef = doc(collection(db, "cities"), "DC"); + +// Set the "capital" field of the city 'DC' +await updateDoc(washingtonRef, { + capital: true +}); +// [END modular_update_document] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/update_document_array.js b/snippets/firestore-next/test-firestore/update_document_array.js new file mode 100644 index 00000000..4db16b62 --- /dev/null +++ b/snippets/firestore-next/test-firestore/update_document_array.js @@ -0,0 +1,20 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/update_document_array.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_update_document_array] +import { collection, doc, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore"; + +const washingtonRef = doc(collection(db, "cities"), "DC"); + +// Atomically add a new region to the "regions" array field. +await updateDoc(washingtonRef, { + regions: arrayUnion("greater_virginia") +}); + +// Atomically remove a region from the "regions" array field. +await updateDoc(washingtonRef, { + regions: arrayRemove("east_coast") +}); +// [END modular_update_document_array] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/update_document_increment.js b/snippets/firestore-next/test-firestore/update_document_increment.js new file mode 100644 index 00000000..8c207b18 --- /dev/null +++ b/snippets/firestore-next/test-firestore/update_document_increment.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/update_document_increment.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_update_document_increment] +import { collection, doc, updateDoc, increment } from "firebase/firestore"; + +const washingtonRef = doc(collection(db, "cities"), "DC"); + +// Atomically increment the population of the city by 50. +await updateDoc(washingtonRef, { + population: increment(50) +}); +// [END modular_update_document_increment] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/update_document_nested.js b/snippets/firestore-next/test-firestore/update_document_nested.js new file mode 100644 index 00000000..acbbf589 --- /dev/null +++ b/snippets/firestore-next/test-firestore/update_document_nested.js @@ -0,0 +1,22 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/update_document_nested.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_update_document_nested] +import { doc, collection, setDoc, updateDoc } from "firebase/firestore"; + +// Create an initial document to update. +const frankDocRef = doc(collection(db, "users"), "frank"); +await setDoc(frankDocRef, { + name: "Frank", + favorites: { food: "Pizza", color: "Blue", subject: "recess" }, + age: 12 +}); + +// To update age and favorite color: +await updateDoc(frankDocRef, { + "age": 13, + "favorites.color": "Red" +}); +// [END modular_update_document_nested] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/update_with_server_timestamp.js b/snippets/firestore-next/test-firestore/update_with_server_timestamp.js new file mode 100644 index 00000000..56cb5cd1 --- /dev/null +++ b/snippets/firestore-next/test-firestore/update_with_server_timestamp.js @@ -0,0 +1,15 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/update_with_server_timestamp.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_update_with_server_timestamp] +import { collection, updateDoc, serverTimestamp } from "firebase/firestore"; + +const docRef = doc(collection(db, 'objects'), 'some-id'); + +// Update the timestamp field with the value from the server +const updateTimestamp = await updateDoc(docRef, { + timestamp: serverTimestamp() +}); +// [END modular_update_with_server_timestamp] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/use_from_cache.js b/snippets/firestore-next/test-firestore/use_from_cache.js new file mode 100644 index 00000000..5e3d96bb --- /dev/null +++ b/snippets/firestore-next/test-firestore/use_from_cache.js @@ -0,0 +1,20 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/use_from_cache.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_use_from_cache] +import { collection, onSnapshot, where, query } from "firebase/firestore"; + +const q = query(collection(db, "cities"), where("state", "==", "CA")); +onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => { + snapshot.docChanges().forEach((change) => { + if (change.type === "added") { + console.log("New city: ", change.doc.data()); + } + + const source = snapshot.metadata.fromCache ? "local cache" : "server"; + console.log("Data came from " + source); + }); +}); +// [END modular_use_from_cache] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/valid_filter_and_order.js b/snippets/firestore-next/test-firestore/valid_filter_and_order.js new file mode 100644 index 00000000..5ef04085 --- /dev/null +++ b/snippets/firestore-next/test-firestore/valid_filter_and_order.js @@ -0,0 +1,10 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/valid_filter_and_order.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_valid_filter_and_order] +import { query, where, orderBy } from "firebase/firestore"; + +const q = query(citiesRef, where("population", ">", 100000), orderBy("population")); +// [END modular_valid_filter_and_order] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/valid_range_filters.js b/snippets/firestore-next/test-firestore/valid_range_filters.js new file mode 100644 index 00000000..27acb533 --- /dev/null +++ b/snippets/firestore-next/test-firestore/valid_range_filters.js @@ -0,0 +1,11 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/valid_range_filters.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_valid_range_filters] +import { query, where } from "firebase/firestore"; + +const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); +const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000)); +// [END modular_valid_range_filters] \ No newline at end of file diff --git a/snippets/firestore-next/test-firestore/write_batch.js b/snippets/firestore-next/test-firestore/write_batch.js new file mode 100644 index 00000000..8ef6f984 --- /dev/null +++ b/snippets/firestore-next/test-firestore/write_batch.js @@ -0,0 +1,26 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-firestore/write_batch.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_write_batch] +import { writeBatch, doc, collection } from "firebase/firestore"; + +// Get a new write batch +const batch = writeBatch(db); + +// Set the value of 'NYC' +const nycRef = doc(collection(db, "cities"), "NYC"); +batch.set(nycRef, {name: "New York City"}); + +// Update the population of 'SF' +const sfRef = doc(collection(db, "cities"), "SF"); +batch.update(sfRef, {"population": 1000000}); + +// Delete the city 'LA' +const laRef = doc(collection(db, "cities"), "LA"); +batch.delete(laRef); + +// Commit the batch +await batch.commit(); +// [END modular_write_batch] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js b/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js new file mode 100644 index 00000000..a81a63e6 --- /dev/null +++ b/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js @@ -0,0 +1,11 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_collection_ratings] +import { collection, doc, getDocs } from "firebase/firestore"; + +const ratingsRef = collection(doc(collection(db, "restaurants"), "arinell-pizza"), "ratings"); +const ratingsDocs = await getDocs(ratingsRef); +// [END modular_get_collection_ratings] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-aggregation/sample_doc.js b/snippets/firestore-next/test-solution-aggregation/sample_doc.js new file mode 100644 index 00000000..0b9717e4 --- /dev/null +++ b/snippets/firestore-next/test-solution-aggregation/sample_doc.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-aggregation/sample_doc.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_sample_doc] +const arinellDoc = { + name: 'Arinell Pizza', + avgRating: 4.65, + numRatings: 683 +} +// [END modular_sample_doc] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-arrays/post_with_array.js b/snippets/firestore-next/test-solution-arrays/post_with_array.js new file mode 100644 index 00000000..1bfbbd63 --- /dev/null +++ b/snippets/firestore-next/test-solution-arrays/post_with_array.js @@ -0,0 +1,16 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-arrays/post_with_array.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_post_with_array] +// Sample document in the 'posts' collection. +{ + title: "My great post", + categories: [ + "technology", + "opinion", + "cats" + ] +} +// [END modular_post_with_array] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-arrays/post_with_map.js b/snippets/firestore-next/test-solution-arrays/post_with_map.js new file mode 100644 index 00000000..2bb106c1 --- /dev/null +++ b/snippets/firestore-next/test-solution-arrays/post_with_map.js @@ -0,0 +1,16 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-arrays/post_with_map.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_post_with_map] +// Sample document in the 'posts' collection +{ + title: "My great post", + categories: { + "technology": true, + "opinion": true, + "cats": true + } +} +// [END modular_post_with_map] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js b/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js new file mode 100644 index 00000000..752b0e29 --- /dev/null +++ b/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js @@ -0,0 +1,16 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_post_with_map_advanced] +// The value of each entry in 'categories' is a unix timestamp +{ + title: "My great post", + categories: { + technology: 1502144665, + opinion: 1502144665, + cats: 1502144665 + } +} +// [END modular_post_with_map_advanced] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-arrays/query_in_category.js b/snippets/firestore-next/test-solution-arrays/query_in_category.js new file mode 100644 index 00000000..d3d7ea2f --- /dev/null +++ b/snippets/firestore-next/test-solution-arrays/query_in_category.js @@ -0,0 +1,14 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-arrays/query_in_category.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_query_in_category] +import { collection, getDocs, query, where } from "firebase/firestore"; + +// Find all documents in the 'posts' collection that are +// in the 'cats' category. +const q = query(collection(db, "posts"), where("categories.cats", "==", true)); +const docs = await getDocs(q); +// ... +// [END modular_query_in_category] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js new file mode 100644 index 00000000..3acbe6aa --- /dev/null +++ b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_query_in_category_timestamp] +import { collection, query, where, orderBy } from "@firebase/firestore"; + +const q = query(collection(db, "posts"), + where("categories.cats", ">", 0), + orderBy("categories.cats")); +// [END modular_query_in_category_timestamp] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js new file mode 100644 index 00000000..de45880f --- /dev/null +++ b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_query_in_category_timestamp_invalid] +import { collection, query, where, orderBy, FirebaseFirestore } from "@firebase/firestore"; + +const q = query(collection(db, "posts"), + where("categories.cats", "==", true), + orderBy("timestamp")); +// [END modular_query_in_category_timestamp_invalid] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-counters/create_counter.js b/snippets/firestore-next/test-solution-counters/create_counter.js new file mode 100644 index 00000000..69202b9c --- /dev/null +++ b/snippets/firestore-next/test-solution-counters/create_counter.js @@ -0,0 +1,24 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-counters/create_counter.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_create_counter] +function createCounter(ref, num_shards) { + import { collection, doc, writeBatch } from "firebase/firestore"; + + const batch = writeBatch(db); + + // Initialize the counter document + batch.set(ref, { num_shards: num_shards }); + + // Initialize each shard with count=0 + for (let i = 0; i < num_shards; i++) { + const shardRef = doc(collection(ref, 'shards'), i.toString()); + batch.set(shardRef, { count: 0 }); + } + + // Commit the write batch + return batch.commit(); +} +// [END modular_create_counter] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-counters/get_count.js b/snippets/firestore-next/test-solution-counters/get_count.js new file mode 100644 index 00000000..2a0031ed --- /dev/null +++ b/snippets/firestore-next/test-solution-counters/get_count.js @@ -0,0 +1,20 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-counters/get_count.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_get_count] +async function getCount(ref) { + import { collection, getDocs } from "@firebase/firestore"; + + // Sum the count of each shard in the subcollection + const snapshot = await getDocs(collection(ref, 'shards')); + + let totalCount = 0; + snapshot.forEach(doc => { + totalCount += doc.data().count; + }); + + return totalCount; +} +// [END modular_get_count] \ No newline at end of file diff --git a/snippets/firestore-next/test-solution-counters/increment_counter.js b/snippets/firestore-next/test-solution-counters/increment_counter.js new file mode 100644 index 00000000..1b676e57 --- /dev/null +++ b/snippets/firestore-next/test-solution-counters/increment_counter.js @@ -0,0 +1,17 @@ +// This snippet file was generated by processing the source file: +// snippets/firestore-next/test-solution-counters/increment_counter.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_increment_counter] +function incrementCounter(db, ref, num_shards) { + import { collection, doc, updateDoc, increment, FirebaseFirestore } from "@firebase/firestore"; + + // Select a shard of the counter at random + const shardId = Math.floor(Math.random() * num_shards).toString(); + const shardRef = doc(collection(ref, 'shards'), shardId); + + // Update count + return updateDoc(shardRef, "count", increment(1)); +} +// [END modular_increment_counter] \ No newline at end of file diff --git a/snippets/functions-next/emulator-suite/functions_callable_call.js b/snippets/functions-next/emulator-suite/functions_callable_call.js new file mode 100644 index 00000000..842525ea --- /dev/null +++ b/snippets/functions-next/emulator-suite/functions_callable_call.js @@ -0,0 +1,16 @@ +// This snippet file was generated by processing the source file: +// snippets/functions-next/emulator-suite/functions_callable_call.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_functions_callable_call] +import { getApp } from "firebase/app"; +import { getFunctions, httpsCallable } from "firebase/functions"; + +const functions = getFunctions(getApp()); +const addMessage = httpsCallable(functions, 'addMessage'); + +const result = await addMessage({ text: ''}); +const sanitizedMessage = result.data.text; +// ... +// [END modular_functions_callable_call] \ No newline at end of file diff --git a/snippets/functions-next/emulator-suite/functions_emulator_connect.js b/snippets/functions-next/emulator-suite/functions_emulator_connect.js new file mode 100644 index 00000000..76e8922b --- /dev/null +++ b/snippets/functions-next/emulator-suite/functions_emulator_connect.js @@ -0,0 +1,12 @@ +// This snippet file was generated by processing the source file: +// snippets/functions-next/emulator-suite/functions_emulator_connect.js +// +// To make edits to the snippets in this file, please edit the source + +// [START modular_functions_emulator_connect] +import { getApp } from "firebase/app"; +import { getFunctions, useFunctionsEmulator } from "firebase/functions"; + +const functions = getFunctions(getApp()); +useFunctionsEmulator(functions, "http://localhost:5001"); +// [END modular_functions_emulator_connect] \ No newline at end of file From b5541b4faeefbdde346838f0fb55fcba9447e390 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:14:51 +0100 Subject: [PATCH 21/22] Fix script file path --- scripts/separate-snippets.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/separate-snippets.ts b/scripts/separate-snippets.ts index c119b9ac..b5d5d9d1 100644 --- a/scripts/separate-snippets.ts +++ b/scripts/separate-snippets.ts @@ -183,13 +183,13 @@ async function main() { } for (const snippetName in config.map) { - const filePath = path.join(snippetDir, `${snippetName}.js`); + const newFilePath = path.join(snippetDir, `${snippetName}.js`); const content = processSnippet( config.map[snippetName], filePath, config.prefix ); - fs.writeFileSync(filePath, content); + fs.writeFileSync(newFilePath, content); } } } From 900fd38fde432f0d1ca06f71574268c8402aca45 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 14 Sep 2020 14:15:34 +0100 Subject: [PATCH 22/22] Snippet preamble fixes --- snippets/firestore-next/emulator-suite/fs_emulator_connect.js | 2 +- snippets/firestore-next/test-firestore/add_ada_lovelace.js | 2 +- snippets/firestore-next/test-firestore/add_alan_turing.js | 2 +- snippets/firestore-next/test-firestore/add_document.js | 2 +- .../firestore-next/test-firestore/add_rating_transaction.js | 2 +- .../firestore-next/test-firestore/array_contains_any_filter.js | 2 +- snippets/firestore-next/test-firestore/array_contains_filter.js | 2 +- snippets/firestore-next/test-firestore/chain_filters.js | 2 +- snippets/firestore-next/test-firestore/cities_document_set.js | 2 +- snippets/firestore-next/test-firestore/city_custom_object.js | 2 +- snippets/firestore-next/test-firestore/collection_reference.js | 2 +- snippets/firestore-next/test-firestore/data_types.js | 2 +- snippets/firestore-next/test-firestore/delete_collection.js | 2 +- snippets/firestore-next/test-firestore/delete_document.js | 2 +- snippets/firestore-next/test-firestore/detach_listener.js | 2 +- snippets/firestore-next/test-firestore/disable_network.js | 2 +- snippets/firestore-next/test-firestore/doc_reference.js | 2 +- .../firestore-next/test-firestore/doc_reference_alternative.js | 2 +- snippets/firestore-next/test-firestore/enable_network.js | 2 +- snippets/firestore-next/test-firestore/example_data.js | 2 +- snippets/firestore-next/test-firestore/example_filters.js | 2 +- snippets/firestore-next/test-firestore/filter_and_order.js | 2 +- .../firestore-next/test-firestore/fs_collection_group_query.js | 2 +- .../test-firestore/fs_collection_group_query_data_setup.js | 2 +- snippets/firestore-next/test-firestore/fs_setup_cache.js | 2 +- snippets/firestore-next/test-firestore/get_all_users.js | 2 +- snippets/firestore-next/test-firestore/get_custom_object.js | 2 +- snippets/firestore-next/test-firestore/get_document.js | 2 +- snippets/firestore-next/test-firestore/get_document_options.js | 2 +- snippets/firestore-next/test-firestore/get_multiple.js | 2 +- snippets/firestore-next/test-firestore/get_multiple_all.js | 2 +- snippets/firestore-next/test-firestore/handle_listen_errors.js | 2 +- snippets/firestore-next/test-firestore/in_filter.js | 2 +- snippets/firestore-next/test-firestore/in_filter_with_array.js | 2 +- .../firestore-next/test-firestore/initialize_persistence.js | 2 +- .../firestore-next/test-firestore/invalid_filter_and_order.js | 2 +- snippets/firestore-next/test-firestore/invalid_range_filters.js | 2 +- snippets/firestore-next/test-firestore/listen_diffs.js | 2 +- snippets/firestore-next/test-firestore/listen_document.js | 2 +- snippets/firestore-next/test-firestore/listen_document_local.js | 2 +- snippets/firestore-next/test-firestore/listen_for_users.js | 2 +- snippets/firestore-next/test-firestore/listen_multiple.js | 2 +- snippets/firestore-next/test-firestore/listen_with_metadata.js | 2 +- snippets/firestore-next/test-firestore/new_document.js | 2 +- snippets/firestore-next/test-firestore/order_and_end.js | 2 +- snippets/firestore-next/test-firestore/order_and_limit.js | 2 +- snippets/firestore-next/test-firestore/order_and_limit_desc.js | 2 +- snippets/firestore-next/test-firestore/order_and_start.js | 2 +- snippets/firestore-next/test-firestore/order_multiple.js | 2 +- snippets/firestore-next/test-firestore/paginate.js | 2 +- .../test-firestore/server_timestamp_resolution_options.js | 2 +- snippets/firestore-next/test-firestore/set_custom_object.js | 2 +- snippets/firestore-next/test-firestore/set_document.js | 2 +- snippets/firestore-next/test-firestore/set_with_merge.js | 2 +- snippets/firestore-next/test-firestore/simple_queries.js | 2 +- snippets/firestore-next/test-firestore/simple_queries_again.js | 2 +- snippets/firestore-next/test-firestore/start_doc.js | 2 +- .../firestore-next/test-firestore/start_multiple_orderby.js | 2 +- .../firestore-next/test-firestore/subcollection_reference.js | 2 +- snippets/firestore-next/test-firestore/transaction.js | 2 +- snippets/firestore-next/test-firestore/transaction_promise.js | 2 +- snippets/firestore-next/test-firestore/update_delete_field.js | 2 +- snippets/firestore-next/test-firestore/update_document.js | 2 +- snippets/firestore-next/test-firestore/update_document_array.js | 2 +- .../firestore-next/test-firestore/update_document_increment.js | 2 +- .../firestore-next/test-firestore/update_document_nested.js | 2 +- .../test-firestore/update_with_server_timestamp.js | 2 +- snippets/firestore-next/test-firestore/use_from_cache.js | 2 +- .../firestore-next/test-firestore/valid_filter_and_order.js | 2 +- snippets/firestore-next/test-firestore/valid_range_filters.js | 2 +- snippets/firestore-next/test-firestore/write_batch.js | 2 +- .../test-solution-aggregation/get_collection_ratings.js | 2 +- snippets/firestore-next/test-solution-aggregation/sample_doc.js | 2 +- snippets/firestore-next/test-solution-arrays/post_with_array.js | 2 +- snippets/firestore-next/test-solution-arrays/post_with_map.js | 2 +- .../test-solution-arrays/post_with_map_advanced.js | 2 +- .../firestore-next/test-solution-arrays/query_in_category.js | 2 +- .../test-solution-arrays/query_in_category_timestamp.js | 2 +- .../test-solution-arrays/query_in_category_timestamp_invalid.js | 2 +- .../firestore-next/test-solution-counters/create_counter.js | 2 +- snippets/firestore-next/test-solution-counters/get_count.js | 2 +- .../firestore-next/test-solution-counters/increment_counter.js | 2 +- .../functions-next/emulator-suite/functions_callable_call.js | 2 +- .../functions-next/emulator-suite/functions_emulator_connect.js | 2 +- 84 files changed, 84 insertions(+), 84 deletions(-) diff --git a/snippets/firestore-next/emulator-suite/fs_emulator_connect.js b/snippets/firestore-next/emulator-suite/fs_emulator_connect.js index 48ef3f16..6b587d39 100644 --- a/snippets/firestore-next/emulator-suite/fs_emulator_connect.js +++ b/snippets/firestore-next/emulator-suite/fs_emulator_connect.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/emulator-suite/fs_emulator_connect.js +// ./firestore-next/emulator-suite.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/add_ada_lovelace.js b/snippets/firestore-next/test-firestore/add_ada_lovelace.js index 849b236c..5fa87298 100644 --- a/snippets/firestore-next/test-firestore/add_ada_lovelace.js +++ b/snippets/firestore-next/test-firestore/add_ada_lovelace.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/add_ada_lovelace.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/add_alan_turing.js b/snippets/firestore-next/test-firestore/add_alan_turing.js index f71a2ea0..300eaa00 100644 --- a/snippets/firestore-next/test-firestore/add_alan_turing.js +++ b/snippets/firestore-next/test-firestore/add_alan_turing.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/add_alan_turing.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/add_document.js b/snippets/firestore-next/test-firestore/add_document.js index 0c5eb640..4f01313c 100644 --- a/snippets/firestore-next/test-firestore/add_document.js +++ b/snippets/firestore-next/test-firestore/add_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/add_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/add_rating_transaction.js b/snippets/firestore-next/test-firestore/add_rating_transaction.js index 2c2b931a..0c3a4281 100644 --- a/snippets/firestore-next/test-firestore/add_rating_transaction.js +++ b/snippets/firestore-next/test-firestore/add_rating_transaction.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/add_rating_transaction.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/array_contains_any_filter.js b/snippets/firestore-next/test-firestore/array_contains_any_filter.js index 66049452..79046a5a 100644 --- a/snippets/firestore-next/test-firestore/array_contains_any_filter.js +++ b/snippets/firestore-next/test-firestore/array_contains_any_filter.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/array_contains_any_filter.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/array_contains_filter.js b/snippets/firestore-next/test-firestore/array_contains_filter.js index 05f5a467..0771fc7a 100644 --- a/snippets/firestore-next/test-firestore/array_contains_filter.js +++ b/snippets/firestore-next/test-firestore/array_contains_filter.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/array_contains_filter.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/chain_filters.js b/snippets/firestore-next/test-firestore/chain_filters.js index cd956507..993d7229 100644 --- a/snippets/firestore-next/test-firestore/chain_filters.js +++ b/snippets/firestore-next/test-firestore/chain_filters.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/chain_filters.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/cities_document_set.js b/snippets/firestore-next/test-firestore/cities_document_set.js index c3a42e82..0950a138 100644 --- a/snippets/firestore-next/test-firestore/cities_document_set.js +++ b/snippets/firestore-next/test-firestore/cities_document_set.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/cities_document_set.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/city_custom_object.js b/snippets/firestore-next/test-firestore/city_custom_object.js index d4d0ca49..c12b5c64 100644 --- a/snippets/firestore-next/test-firestore/city_custom_object.js +++ b/snippets/firestore-next/test-firestore/city_custom_object.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/city_custom_object.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/collection_reference.js b/snippets/firestore-next/test-firestore/collection_reference.js index 4505ab12..fb848405 100644 --- a/snippets/firestore-next/test-firestore/collection_reference.js +++ b/snippets/firestore-next/test-firestore/collection_reference.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/collection_reference.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/data_types.js b/snippets/firestore-next/test-firestore/data_types.js index 1c4b56c4..e783c429 100644 --- a/snippets/firestore-next/test-firestore/data_types.js +++ b/snippets/firestore-next/test-firestore/data_types.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/data_types.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/delete_collection.js b/snippets/firestore-next/test-firestore/delete_collection.js index 870e2fa2..78c73bbb 100644 --- a/snippets/firestore-next/test-firestore/delete_collection.js +++ b/snippets/firestore-next/test-firestore/delete_collection.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/delete_collection.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/delete_document.js b/snippets/firestore-next/test-firestore/delete_document.js index 01700abc..aaa79012 100644 --- a/snippets/firestore-next/test-firestore/delete_document.js +++ b/snippets/firestore-next/test-firestore/delete_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/delete_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/detach_listener.js b/snippets/firestore-next/test-firestore/detach_listener.js index 4de580f6..c22470cd 100644 --- a/snippets/firestore-next/test-firestore/detach_listener.js +++ b/snippets/firestore-next/test-firestore/detach_listener.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/detach_listener.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/disable_network.js b/snippets/firestore-next/test-firestore/disable_network.js index d2ce1151..ad9a62fb 100644 --- a/snippets/firestore-next/test-firestore/disable_network.js +++ b/snippets/firestore-next/test-firestore/disable_network.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/disable_network.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/doc_reference.js b/snippets/firestore-next/test-firestore/doc_reference.js index 641f647e..ce16a0cb 100644 --- a/snippets/firestore-next/test-firestore/doc_reference.js +++ b/snippets/firestore-next/test-firestore/doc_reference.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/doc_reference.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/doc_reference_alternative.js b/snippets/firestore-next/test-firestore/doc_reference_alternative.js index a221a21a..fcef2915 100644 --- a/snippets/firestore-next/test-firestore/doc_reference_alternative.js +++ b/snippets/firestore-next/test-firestore/doc_reference_alternative.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/doc_reference_alternative.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/enable_network.js b/snippets/firestore-next/test-firestore/enable_network.js index 002c51bc..031f90ab 100644 --- a/snippets/firestore-next/test-firestore/enable_network.js +++ b/snippets/firestore-next/test-firestore/enable_network.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/enable_network.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/example_data.js b/snippets/firestore-next/test-firestore/example_data.js index ff1a2573..1b1512c7 100644 --- a/snippets/firestore-next/test-firestore/example_data.js +++ b/snippets/firestore-next/test-firestore/example_data.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/example_data.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/example_filters.js b/snippets/firestore-next/test-firestore/example_filters.js index 622528ea..c0a5eb05 100644 --- a/snippets/firestore-next/test-firestore/example_filters.js +++ b/snippets/firestore-next/test-firestore/example_filters.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/example_filters.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/filter_and_order.js b/snippets/firestore-next/test-firestore/filter_and_order.js index 3b65ba0f..2b4c7751 100644 --- a/snippets/firestore-next/test-firestore/filter_and_order.js +++ b/snippets/firestore-next/test-firestore/filter_and_order.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/filter_and_order.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/fs_collection_group_query.js b/snippets/firestore-next/test-firestore/fs_collection_group_query.js index 8af906b1..0fcf2d4e 100644 --- a/snippets/firestore-next/test-firestore/fs_collection_group_query.js +++ b/snippets/firestore-next/test-firestore/fs_collection_group_query.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/fs_collection_group_query.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js b/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js index 6082bcea..47fd6a4b 100644 --- a/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js +++ b/snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/fs_collection_group_query_data_setup.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/fs_setup_cache.js b/snippets/firestore-next/test-firestore/fs_setup_cache.js index 7c209d8d..4960b369 100644 --- a/snippets/firestore-next/test-firestore/fs_setup_cache.js +++ b/snippets/firestore-next/test-firestore/fs_setup_cache.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/fs_setup_cache.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/get_all_users.js b/snippets/firestore-next/test-firestore/get_all_users.js index 9caba862..57585bda 100644 --- a/snippets/firestore-next/test-firestore/get_all_users.js +++ b/snippets/firestore-next/test-firestore/get_all_users.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/get_all_users.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/get_custom_object.js b/snippets/firestore-next/test-firestore/get_custom_object.js index dfd1d79d..abbf98eb 100644 --- a/snippets/firestore-next/test-firestore/get_custom_object.js +++ b/snippets/firestore-next/test-firestore/get_custom_object.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/get_custom_object.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/get_document.js b/snippets/firestore-next/test-firestore/get_document.js index dd421654..9ff21ba6 100644 --- a/snippets/firestore-next/test-firestore/get_document.js +++ b/snippets/firestore-next/test-firestore/get_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/get_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/get_document_options.js b/snippets/firestore-next/test-firestore/get_document_options.js index 58c5c862..30c0202a 100644 --- a/snippets/firestore-next/test-firestore/get_document_options.js +++ b/snippets/firestore-next/test-firestore/get_document_options.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/get_document_options.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/get_multiple.js b/snippets/firestore-next/test-firestore/get_multiple.js index 78d5261c..520765cf 100644 --- a/snippets/firestore-next/test-firestore/get_multiple.js +++ b/snippets/firestore-next/test-firestore/get_multiple.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/get_multiple.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/get_multiple_all.js b/snippets/firestore-next/test-firestore/get_multiple_all.js index 2c1ad434..b306e657 100644 --- a/snippets/firestore-next/test-firestore/get_multiple_all.js +++ b/snippets/firestore-next/test-firestore/get_multiple_all.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/get_multiple_all.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/handle_listen_errors.js b/snippets/firestore-next/test-firestore/handle_listen_errors.js index 469740c0..76012826 100644 --- a/snippets/firestore-next/test-firestore/handle_listen_errors.js +++ b/snippets/firestore-next/test-firestore/handle_listen_errors.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/handle_listen_errors.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/in_filter.js b/snippets/firestore-next/test-firestore/in_filter.js index 137ae040..4e752152 100644 --- a/snippets/firestore-next/test-firestore/in_filter.js +++ b/snippets/firestore-next/test-firestore/in_filter.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/in_filter.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/in_filter_with_array.js b/snippets/firestore-next/test-firestore/in_filter_with_array.js index 1b9b7cec..b3f1574c 100644 --- a/snippets/firestore-next/test-firestore/in_filter_with_array.js +++ b/snippets/firestore-next/test-firestore/in_filter_with_array.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/in_filter_with_array.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/initialize_persistence.js b/snippets/firestore-next/test-firestore/initialize_persistence.js index 1dda0c5e..174539a1 100644 --- a/snippets/firestore-next/test-firestore/initialize_persistence.js +++ b/snippets/firestore-next/test-firestore/initialize_persistence.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/initialize_persistence.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/invalid_filter_and_order.js b/snippets/firestore-next/test-firestore/invalid_filter_and_order.js index afc31fd2..f24b3766 100644 --- a/snippets/firestore-next/test-firestore/invalid_filter_and_order.js +++ b/snippets/firestore-next/test-firestore/invalid_filter_and_order.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/invalid_filter_and_order.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/invalid_range_filters.js b/snippets/firestore-next/test-firestore/invalid_range_filters.js index d5a693d3..d622ec8f 100644 --- a/snippets/firestore-next/test-firestore/invalid_range_filters.js +++ b/snippets/firestore-next/test-firestore/invalid_range_filters.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/invalid_range_filters.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/listen_diffs.js b/snippets/firestore-next/test-firestore/listen_diffs.js index 299ffc25..96fba665 100644 --- a/snippets/firestore-next/test-firestore/listen_diffs.js +++ b/snippets/firestore-next/test-firestore/listen_diffs.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/listen_diffs.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/listen_document.js b/snippets/firestore-next/test-firestore/listen_document.js index d21ad645..3900cba7 100644 --- a/snippets/firestore-next/test-firestore/listen_document.js +++ b/snippets/firestore-next/test-firestore/listen_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/listen_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/listen_document_local.js b/snippets/firestore-next/test-firestore/listen_document_local.js index c6da4542..09e3b56d 100644 --- a/snippets/firestore-next/test-firestore/listen_document_local.js +++ b/snippets/firestore-next/test-firestore/listen_document_local.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/listen_document_local.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/listen_for_users.js b/snippets/firestore-next/test-firestore/listen_for_users.js index 18060df4..32c9a602 100644 --- a/snippets/firestore-next/test-firestore/listen_for_users.js +++ b/snippets/firestore-next/test-firestore/listen_for_users.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/listen_for_users.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/listen_multiple.js b/snippets/firestore-next/test-firestore/listen_multiple.js index 258151ad..a5377c57 100644 --- a/snippets/firestore-next/test-firestore/listen_multiple.js +++ b/snippets/firestore-next/test-firestore/listen_multiple.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/listen_multiple.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/listen_with_metadata.js b/snippets/firestore-next/test-firestore/listen_with_metadata.js index b555d6d8..93fc59b1 100644 --- a/snippets/firestore-next/test-firestore/listen_with_metadata.js +++ b/snippets/firestore-next/test-firestore/listen_with_metadata.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/listen_with_metadata.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/new_document.js b/snippets/firestore-next/test-firestore/new_document.js index c874e962..c854d854 100644 --- a/snippets/firestore-next/test-firestore/new_document.js +++ b/snippets/firestore-next/test-firestore/new_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/new_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/order_and_end.js b/snippets/firestore-next/test-firestore/order_and_end.js index 3dbda981..23184342 100644 --- a/snippets/firestore-next/test-firestore/order_and_end.js +++ b/snippets/firestore-next/test-firestore/order_and_end.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/order_and_end.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/order_and_limit.js b/snippets/firestore-next/test-firestore/order_and_limit.js index 57f46094..344e231d 100644 --- a/snippets/firestore-next/test-firestore/order_and_limit.js +++ b/snippets/firestore-next/test-firestore/order_and_limit.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/order_and_limit.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/order_and_limit_desc.js b/snippets/firestore-next/test-firestore/order_and_limit_desc.js index 89e3eab1..13dee6bc 100644 --- a/snippets/firestore-next/test-firestore/order_and_limit_desc.js +++ b/snippets/firestore-next/test-firestore/order_and_limit_desc.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/order_and_limit_desc.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/order_and_start.js b/snippets/firestore-next/test-firestore/order_and_start.js index 78013ca8..76c73863 100644 --- a/snippets/firestore-next/test-firestore/order_and_start.js +++ b/snippets/firestore-next/test-firestore/order_and_start.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/order_and_start.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/order_multiple.js b/snippets/firestore-next/test-firestore/order_multiple.js index 064c206f..984b4c9a 100644 --- a/snippets/firestore-next/test-firestore/order_multiple.js +++ b/snippets/firestore-next/test-firestore/order_multiple.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/order_multiple.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/paginate.js b/snippets/firestore-next/test-firestore/paginate.js index d2a0effd..bded9e4e 100644 --- a/snippets/firestore-next/test-firestore/paginate.js +++ b/snippets/firestore-next/test-firestore/paginate.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/paginate.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js b/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js index a71e9954..fcc8fbdd 100644 --- a/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js +++ b/snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/server_timestamp_resolution_options.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/set_custom_object.js b/snippets/firestore-next/test-firestore/set_custom_object.js index 6d6c06a3..e76639b7 100644 --- a/snippets/firestore-next/test-firestore/set_custom_object.js +++ b/snippets/firestore-next/test-firestore/set_custom_object.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/set_custom_object.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/set_document.js b/snippets/firestore-next/test-firestore/set_document.js index 548fb59d..e6c7040b 100644 --- a/snippets/firestore-next/test-firestore/set_document.js +++ b/snippets/firestore-next/test-firestore/set_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/set_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/set_with_merge.js b/snippets/firestore-next/test-firestore/set_with_merge.js index b2e17e19..8957fe29 100644 --- a/snippets/firestore-next/test-firestore/set_with_merge.js +++ b/snippets/firestore-next/test-firestore/set_with_merge.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/set_with_merge.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/simple_queries.js b/snippets/firestore-next/test-firestore/simple_queries.js index 6ea0b924..90449071 100644 --- a/snippets/firestore-next/test-firestore/simple_queries.js +++ b/snippets/firestore-next/test-firestore/simple_queries.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/simple_queries.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/simple_queries_again.js b/snippets/firestore-next/test-firestore/simple_queries_again.js index 9ea640c1..41616318 100644 --- a/snippets/firestore-next/test-firestore/simple_queries_again.js +++ b/snippets/firestore-next/test-firestore/simple_queries_again.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/simple_queries_again.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/start_doc.js b/snippets/firestore-next/test-firestore/start_doc.js index 680041bf..853a75ed 100644 --- a/snippets/firestore-next/test-firestore/start_doc.js +++ b/snippets/firestore-next/test-firestore/start_doc.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/start_doc.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/start_multiple_orderby.js b/snippets/firestore-next/test-firestore/start_multiple_orderby.js index 66773e23..a2782678 100644 --- a/snippets/firestore-next/test-firestore/start_multiple_orderby.js +++ b/snippets/firestore-next/test-firestore/start_multiple_orderby.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/start_multiple_orderby.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/subcollection_reference.js b/snippets/firestore-next/test-firestore/subcollection_reference.js index b7eef5bb..5ea77ae4 100644 --- a/snippets/firestore-next/test-firestore/subcollection_reference.js +++ b/snippets/firestore-next/test-firestore/subcollection_reference.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/subcollection_reference.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/transaction.js b/snippets/firestore-next/test-firestore/transaction.js index 3c5201b1..0591ade9 100644 --- a/snippets/firestore-next/test-firestore/transaction.js +++ b/snippets/firestore-next/test-firestore/transaction.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/transaction.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/transaction_promise.js b/snippets/firestore-next/test-firestore/transaction_promise.js index 2f92799d..9d76243f 100644 --- a/snippets/firestore-next/test-firestore/transaction_promise.js +++ b/snippets/firestore-next/test-firestore/transaction_promise.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/transaction_promise.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/update_delete_field.js b/snippets/firestore-next/test-firestore/update_delete_field.js index d490909b..007db2d3 100644 --- a/snippets/firestore-next/test-firestore/update_delete_field.js +++ b/snippets/firestore-next/test-firestore/update_delete_field.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/update_delete_field.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/update_document.js b/snippets/firestore-next/test-firestore/update_document.js index 64824b65..eb17b744 100644 --- a/snippets/firestore-next/test-firestore/update_document.js +++ b/snippets/firestore-next/test-firestore/update_document.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/update_document.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/update_document_array.js b/snippets/firestore-next/test-firestore/update_document_array.js index 4db16b62..39c59bdb 100644 --- a/snippets/firestore-next/test-firestore/update_document_array.js +++ b/snippets/firestore-next/test-firestore/update_document_array.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/update_document_array.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/update_document_increment.js b/snippets/firestore-next/test-firestore/update_document_increment.js index 8c207b18..05ff44eb 100644 --- a/snippets/firestore-next/test-firestore/update_document_increment.js +++ b/snippets/firestore-next/test-firestore/update_document_increment.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/update_document_increment.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/update_document_nested.js b/snippets/firestore-next/test-firestore/update_document_nested.js index acbbf589..0efd286c 100644 --- a/snippets/firestore-next/test-firestore/update_document_nested.js +++ b/snippets/firestore-next/test-firestore/update_document_nested.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/update_document_nested.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/update_with_server_timestamp.js b/snippets/firestore-next/test-firestore/update_with_server_timestamp.js index 56cb5cd1..3fa9febc 100644 --- a/snippets/firestore-next/test-firestore/update_with_server_timestamp.js +++ b/snippets/firestore-next/test-firestore/update_with_server_timestamp.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/update_with_server_timestamp.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/use_from_cache.js b/snippets/firestore-next/test-firestore/use_from_cache.js index 5e3d96bb..dc689d8a 100644 --- a/snippets/firestore-next/test-firestore/use_from_cache.js +++ b/snippets/firestore-next/test-firestore/use_from_cache.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/use_from_cache.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/valid_filter_and_order.js b/snippets/firestore-next/test-firestore/valid_filter_and_order.js index 5ef04085..fc4d54f0 100644 --- a/snippets/firestore-next/test-firestore/valid_filter_and_order.js +++ b/snippets/firestore-next/test-firestore/valid_filter_and_order.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/valid_filter_and_order.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/valid_range_filters.js b/snippets/firestore-next/test-firestore/valid_range_filters.js index 27acb533..bd39bac2 100644 --- a/snippets/firestore-next/test-firestore/valid_range_filters.js +++ b/snippets/firestore-next/test-firestore/valid_range_filters.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/valid_range_filters.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-firestore/write_batch.js b/snippets/firestore-next/test-firestore/write_batch.js index 8ef6f984..605cdbb7 100644 --- a/snippets/firestore-next/test-firestore/write_batch.js +++ b/snippets/firestore-next/test-firestore/write_batch.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-firestore/write_batch.js +// ./firestore-next/test.firestore.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js b/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js index a81a63e6..2b690134 100644 --- a/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js +++ b/snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-aggregation/get_collection_ratings.js +// ./firestore-next/test.solution-aggregation.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-aggregation/sample_doc.js b/snippets/firestore-next/test-solution-aggregation/sample_doc.js index 0b9717e4..2c25bc70 100644 --- a/snippets/firestore-next/test-solution-aggregation/sample_doc.js +++ b/snippets/firestore-next/test-solution-aggregation/sample_doc.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-aggregation/sample_doc.js +// ./firestore-next/test.solution-aggregation.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-arrays/post_with_array.js b/snippets/firestore-next/test-solution-arrays/post_with_array.js index 1bfbbd63..2c3e5985 100644 --- a/snippets/firestore-next/test-solution-arrays/post_with_array.js +++ b/snippets/firestore-next/test-solution-arrays/post_with_array.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-arrays/post_with_array.js +// ./firestore-next/test.solution-arrays.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-arrays/post_with_map.js b/snippets/firestore-next/test-solution-arrays/post_with_map.js index 2bb106c1..59286b89 100644 --- a/snippets/firestore-next/test-solution-arrays/post_with_map.js +++ b/snippets/firestore-next/test-solution-arrays/post_with_map.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-arrays/post_with_map.js +// ./firestore-next/test.solution-arrays.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js b/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js index 752b0e29..3553248c 100644 --- a/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js +++ b/snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-arrays/post_with_map_advanced.js +// ./firestore-next/test.solution-arrays.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-arrays/query_in_category.js b/snippets/firestore-next/test-solution-arrays/query_in_category.js index d3d7ea2f..3388cdb5 100644 --- a/snippets/firestore-next/test-solution-arrays/query_in_category.js +++ b/snippets/firestore-next/test-solution-arrays/query_in_category.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-arrays/query_in_category.js +// ./firestore-next/test.solution-arrays.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js index 3acbe6aa..6c6c0726 100644 --- a/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js +++ b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-arrays/query_in_category_timestamp.js +// ./firestore-next/test.solution-arrays.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js index de45880f..511acbfd 100644 --- a/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js +++ b/snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-arrays/query_in_category_timestamp_invalid.js +// ./firestore-next/test.solution-arrays.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-counters/create_counter.js b/snippets/firestore-next/test-solution-counters/create_counter.js index 69202b9c..4cc05cb9 100644 --- a/snippets/firestore-next/test-solution-counters/create_counter.js +++ b/snippets/firestore-next/test-solution-counters/create_counter.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-counters/create_counter.js +// ./firestore-next/test.solution-counters.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-counters/get_count.js b/snippets/firestore-next/test-solution-counters/get_count.js index 2a0031ed..dcf61f55 100644 --- a/snippets/firestore-next/test-solution-counters/get_count.js +++ b/snippets/firestore-next/test-solution-counters/get_count.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-counters/get_count.js +// ./firestore-next/test.solution-counters.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/firestore-next/test-solution-counters/increment_counter.js b/snippets/firestore-next/test-solution-counters/increment_counter.js index 1b676e57..53f5f28a 100644 --- a/snippets/firestore-next/test-solution-counters/increment_counter.js +++ b/snippets/firestore-next/test-solution-counters/increment_counter.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/firestore-next/test-solution-counters/increment_counter.js +// ./firestore-next/test.solution-counters.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/functions-next/emulator-suite/functions_callable_call.js b/snippets/functions-next/emulator-suite/functions_callable_call.js index 842525ea..ad4a3bdb 100644 --- a/snippets/functions-next/emulator-suite/functions_callable_call.js +++ b/snippets/functions-next/emulator-suite/functions_callable_call.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/functions-next/emulator-suite/functions_callable_call.js +// ./functions-next/emulator-suite.js // // To make edits to the snippets in this file, please edit the source diff --git a/snippets/functions-next/emulator-suite/functions_emulator_connect.js b/snippets/functions-next/emulator-suite/functions_emulator_connect.js index 76e8922b..3ac3bfc8 100644 --- a/snippets/functions-next/emulator-suite/functions_emulator_connect.js +++ b/snippets/functions-next/emulator-suite/functions_emulator_connect.js @@ -1,5 +1,5 @@ // This snippet file was generated by processing the source file: -// snippets/functions-next/emulator-suite/functions_emulator_connect.js +// ./functions-next/emulator-suite.js // // To make edits to the snippets in this file, please edit the source