How to get access from one collection to another collection in firebase - javascript

how to get access from one collection to another collection in firebase in JS v9

Firebase's JS API v9 brought different changes.
One of the biggest changes is the fact that the DocumentReference don't allow the access to subcollections anymore. Or at least, not directly from the DocumentReference itself, how we used to to with v8.
In v8, for example, we could do something like this:
//say we have a document reference
const myDocument = db.collection("posts").doc(MY_DOC_ID);
//we can access the subcollection from the document reference and,
//for example, do something with all the documents in the subcollection
myDocument.collection("comments").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// DO SOMETHING
});
});
With v9, we have a different approach. Let's say we get our document:
const myDocument = doc(db, "posts", MY_DOC_ID);
As you can note, the way we write the code is different. In v8 we used to write it in a procedural way. With v9, everything switched to a more functional way, where we can use functions such as doc(), collection() and so on.
So, in order to do the same thing we did with the above example and do something with every doc in the subcollection, the code for v9 API should look like this:
const subcollectionSnapshot = await getDocs(collection(db, "posts", MY_DOC_ID, "comments"));
subcollectionSnapshot.forEach((doc) => {
// DO SOMETHING
});
Note that we can pass additional parameters to functions such as collection() and doc(). The first one will always be the reference to the database, the second one will be the root collection and from there onward, every other parameter will be added to the path. In my example, where I wrote
collection(db, "posts", MY_DOC_ID, "comments")
it means
go in the "posts" collection
pick the document with id equals to MY_DOC_ID
go in the "comments" subcollection of that document

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.

Using react native with firestore get().data() returns undefined

I'm just wondering what's wrong with the way I'm fetching data
using firebase with react-native
why does this work
const res = await firestore().collection('users').doc(uid).get();
const data = res.data().todos.todo.work
but this way I get undefined
const res = await firestore().collection('users').doc(uid).collection('todos').doc('todo').get();
const data = res.data().work
I also tried this but got undefined as well
const res = await firestore().collection('users').doc(`${uid}/todos/todo`).get();
const data = res.data().work
what exactly am I missing?
Without seeing your database, I can only guess that you only have a single document and no actual subcollections. It looks like your single document has nested fields call "todo" inside it. A nested field in a document can't be fetched individually using special syntax. You can only read an entire document at once.
Nested fields in Firestore are not subcollections. They are just fields within a single document. The syntax in the second code sample that doesn't work is attempting to read a document in a subcollection, which simply doesn't exist.
I would suggest reviewing the documentation to better understand how fields and subcollections work, and the code you would use to access either one.

How to check that a document has been created in Firestore with RxFire

In my React app, I want to check whether a background firebase function has created the document in Firestore before updating my UI. So I use the docData function from RxFire to subscribe to changes in the specific, "about-to-be-created-from-a-background-function" doc:
const davidDocRef = db.doc('users/david');
// meantime, a firebase function creates "users/david" doc in the background
// I am observing for changes to the firestore doc in my React Component:
useEffect(() => {
docData(davidDocRef,'uid').subscribe(userData => setUserId(userData.uid));
...
// I then check that orgId is not null by assuming that I will get back a doc.id after it has been created it in Firestore
The problem is that userData.uid always returns "david" regardless of the doc being created in Firestore. What am I doing wrong? It seems like it's returning the uid from the path I've set in the reference instead of an actual document path that has been (or should have been) created in firestore. When I change the reference to look for "users/foo" then userData.uid still returns "foo" instead of undefined or throughing an error.
In this case I can instead look for userData.name. This actually works as I get "undefined" if the document has not been stored in Firestore or "David" if it has, but I would expect the example above to work in a similar manner.
The value of the "uid" field is not going to change as it is the reference to the document.
To confirm that the document was created, you should listen for changes in other fields, such as the name, as you already mentioned you do in your question.
Additionally, the same creation/write operations will invoke intermediately the updates.

Firebase FieldPath.documentId() where query issue

I am trying to query my firebase db using the below code but keep getting docuemtnID is undefined. Is my syntax way off as I keep getting Cannot read property 'documentId' of undefined
db.collection("listings")
.where(db.FieldPath.documentId(), "==", element.drawId)
.get()
.then(docRef => {
});
Firebase is imported as import { db } from "../firebase/init";
You can't access FieldPath as a property of the db instance. Without seeing what's in ../firebase/init, it's not possible to say for sure what you need to use instead (as we can't see how you imported/required the Firestore module). In JavaScript web clients, you would typically say firebase.firestore.FieldValue.
But it's worth noting that since queries using FieldPath.documentId() are only ever going to return a single document with the given ID, you could just get() it instead, and be much more clear and concise:
db.collection("listings").doc(element.drawId).get().then(...)
See: Get a document

Cannot find firebase child by key

I am not able to find a firebase object by specifying the specifiv child key and only if I specify the entire path to the object. Why is this?
This works
ref.child(`users/${user.uid}/watchlist/${key}`)
.once('value')
.then(function(snapshot) {
console.log(snapshot.val());
});
This doesn't work
ref.child(key)
.once('value')
.then(function(snapshot) {
console.log(snapshot.val());
});
My firebase connection
export const ref = firebase.database().ref()
I'm not sure how else you would expect it to work? child() is not a "search" function, it only looks at direct children of the reference or child paths that you specify. It does not look through nested paths Firebase structure "searching" for the specified key. That would be incredibly inefficient. And even if it did do that, what would happen if there were multiple matching keys? Would it return all of them? What if they were at different depths? Etc.
The Firebase real time database is basically a big JSON-like data tree. The only way to get to a bit of data that you want is to know the entire path to that data. Otherwise there wouldn't be any structure at all.
I suppose if you wanted to, you could load the entire Firebase data structure and then write your own function for finding arbitrary keys, no matter where they were in the tree. But that has the same problematic inefficiencies as if it were built into the Firebase library itself - which, it is not.
Perhaps this will illustrate better how child() works. This:
ref.child(`users/${user.uid}/watchlist/${key}`);
Is basically the same as this:
ref.child("users").child(user.uid).child("watchlist").child(key);
Although I suspect that the second method is less efficient, I don't know for sure.

Categories

Resources