NgSysV: Firestore CRUD templates
This post series is indexed at NgateSystems.com. You'll find a super-useful keyword search facility there too.
Last reviewed: Nov '24
Introduction
Google's extensive online documentation for Firestore CRUD (create, read, update, delete) instructions may be too detailed for everyday use. Here are templates for the most important Firestore functions. I suggest you cut and paste them as is and then replace the word "my" in variable names with some suitable contraction of the collection name that you're targetting. For example, references to a collection called "Lecture_events" might be coded as "lecEvtsCollRef".
Creating documents
To create a document containing a myDocData object with an automatically-generated id:
let myDocData = .... create an object containing your data item properties ..... const myCollRef = collection(db, "myCollectionName"); const myDocRef = doc(myCollRef); await setDoc(myDocRef, myDocData);
Note that, confusingly, Google Documentation on 'Adding Data' references an addDoc function as an alternative to setDoc. See the Postscript below for advice on why setDocis preferred.
In the code snippet above, the myDocRef= statement is the point at which an auto-id is allocated. If you need to find the value that's been assigned, you'll find this at myDocRef.id. Again, see the Postscript below for further information on this point.
To create a document with a data item as its identifier :
let myDocData = .... create a data object ..... let myDocumentIdentifier = .... create your identifier .... const myDocRef = doc(db, "myCollectionName", myDocumentIdentifier) await setDoc(myDocRef, myDocData);
Reading documents
To retrieve an individual document using its document id:
const myDocRef = doc(db, "myCollectionName", myDocId); const myDoc = await getDoc(myDocRef); if (myDoc.exists()) { console.log("Document data:", myDoc.data()); }
To retrieve a selection of documents with selection and ordering criteria (example):
const myCollRef = collection(db, "myCollectionName"); const myQuery = query(myCollRef, where("myField1Name", "==", myField1Value), orderBy("myField2Name", "asc")); const mySnapshot = await getDocs(myQuery); mySnapshot.forEach((myDoc) => { console.log(myDoc.id, " => ", myDoc.data()); });
Within a Snapshot's forEach, the data for a document is available as myDoc.data(), the document's docRef is myDoc.ref and its docId as myDoc.id. If you're just interested in determining the existence of document(s) that match the selection criteria, a useful trick is to check for non-zero mySnapshot.size.
If you want to refer to individual documents in the snapshot array, you'll find the data for the n'th entry at mySnapshot.docs[n].data() and its id at mySnapshot.docs[n].id
Note that if you don't specify an orderBy field, documents will be returned in ascending order of docId. And if you include more than one where field, you must create a (compound) index. The browser inspection tool will help you here. You only need to follow the link in the "index-needed" error message. Individual fields are indexed automatically in a Firestore database.
To retrieve all of the documents in a collection:
const myCollRef = collection(db, "myCollectionName"); const myQuery = query(myCollRef); const mySnapshot = await getDocs(myQuery); mySnapshot.forEach((myDoc) => { console.log(myDoc.id, " >= ", myDoc.data()); });
Firestore comparison operators are "==", ">" , "<", "<=", ">=" and "!=", plus some interesting array membership operators.
To retrieve all of the documents in a hierarchy of collections and then do something:
You have to be careful when you want to perform a certain action after processing on a multi-level hierarchy of collections has concluded. If your code contains many nested foreach statements, each containing an await instruction, you can't rely on the individual awaits to tell you when the whole set has finished. Each of these individual awaits occupies a separate thread and these do not communicate directly with each other in any helpful way.
One way out of this problem is to use the traditional for loop on your snapshots rather than forEachs. Here's an example targeting all the children in a sub-collection before performing an action
let myDocData = .... create an object containing your data item properties ..... const myCollRef = collection(db, "myCollectionName"); const myDocRef = doc(myCollRef); await setDoc(myDocRef, myDocData);
Here, you can rely on your awaits to be performed in strict sequence, and when you hit the end of the loop you know you can carry on confidently to perform your dependant action. But the performance hit created by this may be significant and so you might be interested in the following arrangement:
You can get a handle on the individual promises launched by the awaits in a forEach loop by storing them in an array. You can then apply an await Promise.all instruction to this array to find out when all its member promises are done. It is impossible to provide a simple template here to suit all circumstances, but the following is a "sketch" that illustrates the broad principles.
Here, a two-level hierarchy involving two separate collections (parents and children) is linked by a common parentsId field. The two collections are read into memory to permit analysis of the aggregate. This can only be done when all the children have been read.
let myDocData = .... create a data object ..... let myDocumentIdentifier = .... create your identifier .... const myDocRef = doc(db, "myCollectionName", myDocumentIdentifier) await setDoc(myDocRef, myDocData);
Updating a document
Example - to change the value of the myField property in a document's myDocData content
const myDocRef = doc(db, "myCollectionName", myDocId); const myDoc = await getDoc(myDocRef); if (myDoc.exists()) { console.log("Document data:", myDoc.data()); }
Example - to replace the entire content of document myDocId with a new object containing only a myField property
const myCollRef = collection(db, "myCollectionName"); const myQuery = query(myCollRef, where("myField1Name", "==", myField1Value), orderBy("myField2Name", "asc")); const mySnapshot = await getDocs(myQuery); mySnapshot.forEach((myDoc) => { console.log(myDoc.id, " => ", myDoc.data()); });
You can apply changes to several fields simultaneously by replacing the {myField: myFieldValue} bit in the above examples with an object containing the fields you want to change.
Deleting a document
const myCollRef = collection(db, "myCollectionName"); const myQuery = query(myCollRef); const mySnapshot = await getDocs(myQuery); mySnapshot.forEach((myDoc) => { console.log(myDoc.id, " >= ", myDoc.data()); });
CRUD operations within transactions
Inside a transaction, the patterns introduced above remain unchanged but the setDoc commands are amended as follows:
Within the runTransaction(db, async (transaction) => { ... }).catch(); function:
- getDoc is replaced by transaction.get()
- setDoc is replaced by transaction.set()
- deleteDoc is replaced by transaction.delete()
Postscript
As mentioned above, Google provides addDoc() and updateDoc() functions for document creation and update in parallel with setDoc(). But this seems unnecessarily confusing when setDoc can perform both operations. Also, when it comes to transactions, addDoc() can only be used to create documents with auto ids. It seems simpler, in practice, just to use setDoc everywhere.
You may have noticed that there's no await on the doc(myCollRef) call that creates a Firestore document identifier. This tells you that Firestore somehow manages to do this without actually visiting the collection and seeing what is already in use. If you're curious about how it manages this you might like to check out the discussion at StackOverflow.
Google documentation references
Add data to Cloud Firestore : https://firebase.google.com/docs/firestore/manage-data/add-data
Read data with Cloud Firestore : https://firebase.google.com/docs/firestore/query-data/get-data
Delete data from Cloud Firestore : https://firebase.google.com/docs/firestore/manage-data/delete-data
SDK documentation can be found at:
- https://firebase.google.com/docs/reference/js/firestore_ and
- https://firebase.google.com/docs/reference/js/firestore_.transaction
The above is the detailed content of NgSysV: Firestore CRUD templates. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.
