Home > Web Front-end > JS Tutorial > NgSysV: Firestore CRUD templates

NgSysV: Firestore CRUD templates

Linda Hamilton
Release: 2024-12-04 05:31:15
Original
946 people have browsed it

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);
Copy after login
Copy after login

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);
Copy after login
Copy after login

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());
} 
Copy after login
Copy after login

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());
});
Copy after login
Copy after login

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());
});
Copy after login
Copy after login

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);
Copy after login
Copy after login

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);
Copy after login
Copy after login

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());
} 
Copy after login
Copy after login

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());
});
Copy after login
Copy after login

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());
});
Copy after login
Copy after login

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

  1. 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.

  2. 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!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template