How to get the complete document path in firebase firestore? - javascript

I managed to get all the documents and document IDs inside all 'sheets' collection in firestore.
Refer to below code -
const baseRef = admin.firestore().collectionGroup("sheets").where("date", "==", date);
const querySnap = await baseRef.get();
const docSnap = querySnap.docs;
docSnap.forEach((doc) => {
console.log("DOC ID ---->>>", doc.id);
// Here I want to get all the required documents from 'members' subcollection present inside this document
});
Now each of these documents contain a subcollection called 'members'. I want only documents from 'members' collection where "memberId" is equal to 'memberId'. How can I get those documents?
I tried the following code but it didn't worked -
const baseRef = admin.firestore().collectionGroup("sheets").where("date", "==", date).collectionGroup("members").where("memberId", "==", memberId);
const querySnap = await baseRef.get();
const docSnap = querySnap.docs;
docSnap.forEach((doc) => {
console.log("DOC ID ---->>>", doc.id);
});
It returned following error -
admin.firestore(..).collectionGroup(..).....is not a function

You cannot define a Query by calling twice the collectionGroup() method as you do with:
const baseRef = admin.firestore().collectionGroup("sheets").where("date", "==", date).collectionGroup("members").where("memberId", "==", memberId);
One solution would be to replicate the date field in the member documents (i.e. copying the field value from the parent sheet docs to their member children docs) and define the Query as follows:
const baseRef = admin.firestore().collectionGroup("members").where("memberId", "==", memberId).where("date", "==", date);
Note that you'll need to build a composite index and that you should not have other subcollections named members in your database.

Related

Firestore: Unable to fetch document from query - doc.data is not a function

here usersList contains the list of username of people and androidNotificationToken is the field in the document of the user which contains the token for sending the notification.
const registrationTokens=[];
const indexOfSender=usersList.indexOf(senderUsername); // to remove the name of person sending message
let removedUsername=usersList.splice(indexOfSender,1);
usersList.forEach(async(element)=>{
const userRef = admin.firestore().collection('users').where("username","==",element);
const doc = await userRef.get();
registrationTokens.push(doc.data().androidNotificationToken);
});
The error on running the cloud computing am receiving is :-
TypeError: doc.data is not a function
at usersList.forEach (/workspace/index.js:191:37)
at process._tickCallback (internal/process/next_tick.js:68:7)
userRef.get() is going to return a QuerySnapshot (not a DocumentSnapshot) object that can contain 0 or more documents matched from the query. Use the API provided by QuerySnapshot to find the resulting documents, even if you are expecting only one document.
If you are expecting just one document from the query, you should at least verify that you got one before indexing into the result set.
const query = admin.firestore().collection('users').where("username","==",element);
const qsnapshot = await query.get();
if (qsnapshot.docs.length > 0) {
const doc = qsnapshot.docs[0];
const data = doc.data();
}
else {
// decide what you want to do if the query returns nothing
}

How to query for objects with a certain property in a Firestore collection, Firebase

I am trying to query for objects in firestore collection with a certain property, my Firestore DB looks as shown in the below picture.
The below code does not work as I am interested in querying for objects based on the the property inside an object. In this case I want all the cases (objects) with "status"=="treated" Is there a way to do it ?
const db = firebase.firestore();
const casesRef = db.collection("mgm/hospital/cases");
// Create a query against the collection.
var query = casesRef.where("status", "==", "active").limit(25);
const queryRef = query.get();
queryRef.then(function(documentSnapshots) {
const cases = documentSnapshots.docs.map((doc) => doc.data());
console.log(cases);
});
Since the field patientDetails is a map, the following should do the trick:
var query = casesRef.where("patientDetails.status", "==", "active").limit(25);

What does .where.get() return?

i am new this website and to mobile programming.
My questions is:
In firebase i have a collection path with some documents.
.collection(maybe).doc(random)
Each doc has subcollection as well.
Also each doc has data such as:
roomName: randomName
roomPassword: randomPass.
So, now i would like to use the query with .where operator and .get like this:
const docRef=db.collection(‘maybe’)
docRef.where(‘roomName’ ‘==‘ ‘randomName’).get()
My question is what do i get back? As i understand i get the querySnapshot, but i do not fully get how to get the second field in data specifically i.e. how to get roomPass?
const docRef = db.collection(‘maybe’);
const futureSnapshot = docRef.where(‘roomName’,‘==‘,‘randomName’).get();
gives you a promise of snapshot.
You have to "await".
const docRef = db.collection(‘maybe’);
const snapshot = await docRef.where(‘roomName’,‘==‘,‘randomName’).get();
after that you can get your data :
const room = snapshot.data(); // undefined if your query has no results
This link could help you
Happy coding !
EDIT
If your document looks like this :
{
randomName: "a name",
randomPassword: "a password"
}
Then you get your data like that :
const room = snapshot.data(); // undefined if your query has no results
const { randomPassword } = room;

Firestore transaction: set id of the first document to the second document

I'm trying to add two documents to two different collections.
say coll1 & coll2.
I add a document to coll1 => I get the document id which I would like to set it to the coll2 document as id, I can simply write two add's but I'm trying to get these done in a transaction, so that if one fails both fail.
I could not get that done using this link
Below is the code I've, which needs to be turned to transations/batched:
await db.runTransaction(
async function (transaction) {
const coll1 = {
text: 'This is collection 1 text',
}
const coll1Doc = await db
.collection('coll1')
.add(coll1)
// I tried transaction.set(db.collection('coll1').doc(), coll1) but this doesn't return the doc or the docId which we need in the next step.
// Similay batch.set is also not returning the newly added/edited doc or its Id.
if (coll1Doc && coll1Doc.id) {
const coll1Id = coll1Doc.id
const coll2 = {
text: 'This is collection 2 text',
}
await db
.collection('coll2')
.doc(coll1Id)
.set(coll2)
}
}
)
Firestore document IDs are generated inside your application code, and are statistically guaranteed to be unique. So your add() call, essentially takes these two steps:
Generate a new unique ID
Create a DocumentReference for that ID
Set the data in that DocumentReference
With that knowledge, you can build a DocumentReference yourself based on an ID that you get without using the transaction object.
const coll1Doc = db
.collection('coll1')
.doc();
const id1 = coll1Doc.id;
await coll1Doc.set(coll1);
Now you can use id1 in the second write operation.

Firebase Database: why do the key/ref in my queried datasnapshot refer to its parent?

I would like to delete an entry from the realtime database that i looked up through a query but i am getting unexpected results for both the ref and key properties.
ref('photos/users/USERID')
.orderByChild('photoname')
.equalTo('photoname i want to look up')
.limitToFirst(1)
.query('once')
.then(snapshot => {
// correct data at 'photos/users/USERID/PHOTOID'
const entry = snapshot.val();
// seems to be the ref to photos/users/USERID'
const ref = snapshot.ref;
// seems to be USERID
const key = snapshot.key
})
Why aren't these the ref/key to the entry i just found? And what is the best approach to remove this entry?
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
Your code needs to take this list into account, and iterate over snapshot.forEach() to get the actual matching item:
ref('photos/users/USERID')
.orderByChild('photoname')
.equalTo('photoname i want to look up')
.limitToFirst(1)
.query('once')
.then(snapshot => {
snapshot.forEach(child => {
const entry = child.val();
const ref = child.ref;
const key = child.key
});
})
Your ref and key are based on ref('photos/users/USERID'), not the filtered subset you have created. Is there any reason you wouldn't call ref('photos/users/USERID/PHOTOID')?

Categories

Resources