explanation of firebase docs about query(query, queryConstraints)? - javascript

I was looking about more details about the query function in firestore in docs reference of firestore and I found this pseudo syntax :
query(query, queryConstraints)
but in all firestore examples about this function they used in the first parameter a collection reference not query
form firestore examples :
// 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"));
Is it the same function or this is another Signature for it ?

A collection reference is a subclass of a query, so wherever the API expects a Query you can also pass a CollectionReference. So you can build a new query by passing a CollectionReference to the query function, or add conditions to an existing query by passing a Query to it.

Related

Trying to get all the collection data from Firestore

I am getting the following Error while trying to get all the data of a Collection from a Firestore
I have a collection names users in my Firestore DB
I am using Firebase Web version 9 (Modular)
const querySnapshot = await getDocs(collection(db, "users"));
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.data());
});
I am using the code from the Official documentation and still getting that error
https://firebase.google.com/docs/firestore/query-data/get-data#web-version-9_6
still this is what i get
TypeError: (0 , lib_firebase__WEBPACK_IMPORTED_MODULE_4__.collection) is not a function
Have you used the this line in your code -
import { collection, getDocs } from "firebase/firestore"; because without importing the collection function won't be accessible and can generate the error.
There are a few possible reasons for this error:
You might have imported the wrong module or a module that does not contain the collection function. Make sure you have imported the Firebase library correctly and that you are using the correct version of the library.
You might have mistyped the name of the function. Make sure you are using the correct spelling and capitalization of the function name.
You might be trying to use the collection function on an object that is not a Firestore instance. The collection function is a method of the Firestore class, so you need to make sure you are calling it on a Firestore instance.

Firestore - Update an array of type DocumentReference

I am using Firestore as a quasi-relational database for a side project. In the Console GUI, I can create an array of DocumentReferences, and then use the values in that array to load child components when needed. I would like to do the same in my code but am unable to.
I have tried:
constructor(private store: AngularFirestore) {}
this.store
.collection('owners')
.doc(this.owner.id)
.update({
trucks: [
...this.owner.trucks, // firestore array of references
this.store.doc(`/truck/${documentReference.id}`),
],
});
But that stores the value as a string in Firestore.
Is there a way to store the value as an instance of DocumentReference?
You can use arrayUnion() if you want to push a new element to an array in Firestore document instead of fetching existing values first as shown below:
import { arrayUnion } from "firebase/firestore";
// ...
this.store
.collection('owners')
.doc(this.owner.id)
.update({
trucks: arrayUnion(this.store.doc(`/truck/${documentReference.id}`),
});
The value should be a DocumentReference if you pass the result of doc() directly in either of the code snippets. Can you confirm it by hovering on the field? It should show the type.

Firestore - Store a property id is reference type by firestore Batch transaction

I trying to store data content reference type by batch transaction, then I got an exception:
Function WriteBatch.set() called with invalid data. Unsupported field value: a custom object (found in document orders/OC9dZErupEhPsamp8QEd)
Is there a way we can use batch transaction to store reference type?
this is my code:
batch.update(orderRef, {
userId: firestore.doc(userId),
});
Normaly update() use to update existing firestore data. Review firestore docs for the same. In that given example they are updating population by increments of value or with new population number but before passing it in each update function values are stored in one cost value if it is not static value. as Asked by #dharmaraj please edit your questions by posting with full code you can also read given firestore documentation for your own studies.
import firebase from "firebase/app";
const app = firebase.initializeApp({});
const firestore = app.firestore();
const batch = firestore.batch();
const newUserId = firestore.doc(userId);
batch.update(orderRef, {
userId: newUserId,
});
Log newUserId value and see what are you getting into it.
You can't store the reference object that doc() returns, it's an object that may have circular references and functions in it. doc() is not the id of the document. If you want to get the id (which is a string), then:
const newUserId = firestore.doc(userId).ref.id;
batch.update(orderRef, {
userId: newUserId,
});
I don't know why batch validate input should be a pure object. I tried to push reference type id inside nested object then it work well, yeah I know it already is a trick, but it work.
change:
batch.update(docRef, {
user: firestore.collection('users').doc(userId)
})
to:
batch.update(docRef, {
user: {
id: firestore.collection('users').doc(userId)
}
})

How do you create a new Firestore document within a transaction

I'm trying to log changes to a collection of customer records. In order to keep things watertight,the log records should obviously be created within a Firestore transaction. I have no problems using transaction.set to apply the customer document changes, but every such change needs to be accompanied by the creation of a new document within my transactionLogs collection. Here, things are going badly wrong The log documents are identified by a timestamp field and when I run the following code: ...
import { initializeApp } from 'firebase/app';
import {
getFirestore, collection, query, getDoc,
getDocs, where, orderBy, addDoc, doc, updateDoc, deleteDoc, runTransaction
} from 'firebase/firestore';
var firebaseApp = initializeApp(firebaseConfig);
var db = getFirestore(firebaseApp);
// code to read and validate update to customer documents and to call the following asynch function
function performCustomerUpdate(parameters) {
await runTransaction(db, async (transaction) => {
// update Customer document and build a transactionLog object
const newLogRef = collection(db, 'transactionLogs', transactionLog.timeStamp);
await transaction.set(newLogRef, transactionLog);
});
}
... the transaction.set instruction fails saying something like "Invalid collection reference. Collection references must have an odd number of segments, but transactionsLogs/1645451217221 has 2." In this particular instance, 1645451217221 would have been the value of transactionLog.timesStamp.
Does anyone have advice on what is going on here and how to fix the error? My understanding is that transaction.set will create a new record if the supplied reference doesn't exist, so I ought to be on the right lines. But why does Firestore think that I want to create it in a collection called transactionsLogs/1645451217221? How do I get it the create a reference for a document identified by the string '1645451217221' in a collection called 'transactionsLogs'?
If you are specifying the document ID (and not using the auto-generated IDs) then you must use doc() instead of collection() to create a DocumentReference:
const newLogRef = doc(db, 'transactionLogs', transactionLog.timeStamp);
The collection() function is used create a CollectionReference.
Also checkout: Firestore: What's the pattern for adding new data in Web v9?
My understanding is that transaction.set will create a new record if the supplied reference doesn't exist
If the documents exists, the it'll overwrite the existing document.
With regard to the wider question of how you add records within a transaction, the answer is that you would use pretty much the same code as you'd use outside a transaction.
So whereas outside a transaction you would create a new document with a data item as its identifier with the following Web Version 9 code:
const myDocRef = doc(db, "myCollection", myDocId);
await setDoc(myDocRef, myDocData);
Inside a transaction, you use exactly the same pattern with the one exception that setDoc() is replaced by transaction.set() and the whole operation (obviously) is surrounded by a runTransaction(db, async (transaction) => { instruction:
await runTransaction(db, async (transaction) => {
const myDocRef = doc(db, "myCollection", myDocId);
await transaction.set(myDocRef, myDocData);
}).catch((error) => {
alert(`Oops - transaction failed - error is : ${error}`);
});
Similarly, the pattern used to create a document with an automatically-generated id:
const myCollectionRef = collection(db, "myCollection");
const myDocRef = doc(myCollectionRef)
await setDoc(myDocRef, myDocData);
is replaced within a transaction by
const myCollectionRef = collection(db, "myCollection");
const myDocRef = doc(myCollectionRef)
await transaction.set(myDocRef, myDocData);
Note that if you find you need to find the value that's be assigned to your automatically-generated id, this is available as myDocRef.id

Firebase JS9 access subcollection with DocumentSnapshot

Just quick question.
How to do something like this in firebase javascript v9? userDoc is a DocumentSnapshot .
const postRef = userDoc.ref.collection('posts').doc(slug);
I need to access sub-collection with doc snapshot, but I am totally clueless.
You can pass the document reference to the collection function, and the collection ref that gives to the doc function:
const postRef = doc(collection(userDoc.ref, 'posts', slug));
Alternatively, you can skip the collection call here as both collection and doc accept multiple arguments:
const postRef = doc(userDoc.ref, 'posts', slug);

Categories

Resources