This question already has answers here:
Firestore order by two fields
(1 answer)
How can I order a cloud firestore snapshot with 2 fields?
(2 answers)
Closed 1 year ago.
I'm using google Firestore as my database, I wanted to order my material table by two fields (name and date) so I can have it in alphabetical order + in the date it was created, however I got the following error:
This is my code with "acudiente" being the name of the user and "fecha" being the date of the order and "pedidos" being the collection.
useEffect(() => {
const usuariosRef = db.collectionGroup('pedidos')
usuariosRef.orderBy("acudiente", "fecha").onSnapshot(snapshot => {
const tempData = [];
snapshot.forEach((doc) => {
const data = doc.data();
tempData.push(data);
console.log(tempData)
});
setPedidos(tempData);
})
}, []);
Related
This question already has answers here:
How to use for in loop and query data from firebase
(2 answers)
Using getDoc().then() inside of a loop Firebase
(2 answers)
How do i use array.push on async loop?
(2 answers)
Fetch in fetch inside a loop JS
(2 answers)
Closed 17 days ago.
I tired with the suggested answer, it is not working in my case.
I am fetching data from a database and storing it in arrays so I can sort the array values later.
But when I check the data from the sorted array in the console it is showing the right output but when I display it on the page it is not.
Basically the array arr stores data of one user and then I find the last element of the array and write 'update' to it.
But it is only showing 'update' to the second user's (last in Db) and writing 'update' to it.
How do I get the right output displayed on the page i.e. showing 'update' to each user's last entry?
(() => {
setTimeout(() => {
let arr = [];
for (let email of userEmails) {
docRef
.where("emailInDb", "==", email)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
let startDate = new Date(doc.data().dateInMills.at(-1) * 1000);
// Adding data to the array
arr.push({
id: doc.id,
email: doc.data().email,
convertedDate: startDate,
});
});
arr.sort((a, b) => {
return a.convertedDate - b.convertedDate;
});
console.log(arr.at(-1)); // This is the correct output shown in console.
dataOnPage.innerHTML = "";
for (let data of arr) {
let detailsOfUsers = `
<div class="flex flex-col justify-center align-middle tableRow">
<span>
<span class='name'>${data.name} </span>
<span class='email block text-[10px] text-gray-400 font-medium'>${
data.email
} </span>
<span class='updateStatus'>${
data === arr.at(-1) ? "udpate" : ""
}
// Here it is only showing update for one record.
</span>
</span>
</div>
`;
dataOnPage.innerHTML += detailsOfUsers;
}
});
}
}, 1000);
})();
This question already has answers here:
javascript filter array multiple conditions
(27 answers)
Closed 1 year ago.
I am creating a simple app where I want to filter the list of hardcoded employees based on different categories.
This is my employees class:
export class Emp{
eid:number
name:string
department:string
age:number
skills:number
}
I have created a search box in html such that user can search either by entering name or dept or eid of an employee and get the details of respective employee. For example
employees:Emp[]=[
{eid:1,name:"Vikram",age:29,department:"HTML5",skills:5},
{eid:5,name:"Vetaal",age:28,department:"CSS",skills:2.5},]
Now if a user searches for 5 then he should get the details of both these employees since 5 being in HTML5 and EID.
This is the logic I am using:
export class EmpDetailsComponent implements OnInit {
private _eidfilter:string;
get eidfilter():string {
return this._eidfilter
}
set eidfilter(value : string){
this._eidfilter=value
this.filteredemp=this.performfilter(value.toString());
}
filteredemp:Emp[]=[];
performfilter(filterBy:string): Emp[] {
filterBy=filterBy.toLowerCase()
return this.employees.filter((employee:Emp)=>employee.eid.toString().toLowerCase().includes(filterBy)),this.employees.filter((employee:Emp)=>employee.department.toLowerCase().includes(filterBy))
}
The problem I am facing is that whatever I return second in performfilter function only that is being shown in the required list for example if I code : return <<department>> , <<eid>> then it returns on the basis of eid only
Use OR condition in your filter() method
performfilter(filterBy: string): Emp[] {
filterBy = filterBy.toLowerCase()
return this.employees.filter((employee: Emp) => employee.eid.toString().toLowerCase().includes(filterBy) || employee.department.toLowerCase().includes(filterBy))
}
This question already has answers here:
Compare two dates with JavaScript
(43 answers)
Closed 2 years ago.
I have an array that has a startTime. I want to get items where startTime in between 2020-12-10 09:30:00 and 2020-12-10 13:20:00. I am using the filter method to get the items from the array.
startTime>'2020-12-10 09:30:00' // is working, returns array with 6 items
but when i add startTime>'2020-12-10 09:30:00' && startTime<'2020-12-10 13:20:00' // returns null
not able to understand why it not filtering the result when I use less than
here is my code
var empStart = empShift.filter(item => {
return item.startTime>'2020-12-10 09:30:00' && item.startTime<'2020-12-10
13:20:00'
})
Thanks for the response guys I came to know whats my mistake
var empStart = empShift.filter(item => {
return new date(item.startTime).getTime() >'2020-12-10 09:30:00' && new
date(item.startTime).getTime() <'2020-12-10 13:20:00'
})
new date(//variable).getTime() // solved my issue
I am trying to order a query by timestamp.
In my document I have a field called "date" which has this form:
date = {
nanoseconds: 963000000,
seconds: 1594917688
}
In my code I have this:
let photosArray = [];
firebase
.getDatabase()
.collection("photos")
.doc(firebase.getCurrentUser().uid)
.collection("userPhotos")
.orderBy("date", "asc") // Sorted by date in ascending direction
.onSnapshot((snapshot) => {
let changes = snapshot.docChanges();
changes.forEach((change) => {
if (change.type === "added") {
// Get the new photo
const photo = change.doc.data();
// Add the photo to the photos list
photosArray.push(photo);
}
});
// The last photo is at the top of the list
setPhotos(photosArray);
But when I render the list of photos, they are unsorted... For example: the first one taken 2 hours ago, the second one taken 1 minute ago, and the last one taken 2 years ago.
UPDATE
This is how I store the date in firestore
Firebase.js:
getTimestamp = () => firebase.firestore.FieldValue.serverTimestamp();
PhotoUploader.js
await firestore
.collection("photos")
.doc(userId)
.collection("userPhotos")
.add({
id,
date: firebase.getTimestamp(),
});
If your date field shows a map with two nested fields, that is not really a timestamp, and it won't sort the way you expect. You should take a look at the code that adds the date field to the document, and make sure it uses a timestamp correctly. Either that, or use a single timestamp numeric value that will sort the way you expect.
This question already has answers here:
Cloud Firestore collection count
(29 answers)
How to get count of documents in a collection? [duplicate]
(2 answers)
Closed 2 years ago.
I want to get the total number of documents inside a firestore collection, I'm making a forum app, so I want to show the current amount of comments inside each discussion.
There's something like db.collection("comments").get().lenght or something like that?
With the size property of the QuerySnapshot, you can get the number of documents of a collection, as follows:
db.collection("comments").get().then(function(querySnapshot) {
console.log(querySnapshot.size);
});
HOWEVER, you should note that this implies that you read all the documents of the collection each time you want to get the number of documents and, therefore, it has a cost.
So, if your collection has a lot of documents, a more affordable approach would be to maintain a set of distributed counters that hold the number of documents. Each time you add/remove a document, you increase/decrease the counters.
Based on the documentation, here is how to do for a write:
First, initialize the counters:
const db = firebase.firestore();
function createCounter(ref, num_shards) {
let batch = db.batch();
// Initialize the counter document
batch.set(ref, { num_shards: num_shards });
// Initialize each shard with count=0
for (let i = 0; i < num_shards; i++) {
let shardRef = ref.collection('shards').doc(i.toString());
batch.set(shardRef, { count: 0 });
}
// Commit the write batch
return batch.commit();
}
const num_shards = 3; //For example, we take 3
const ref = db.collection('commentCounters').doc('c'); //For example
createCounter(ref, num_shards);
Then, when you write a comment, use a batched write as follows:
const num_shards = 3;
const ref = db.collection('commentCounters').doc('c');
let batch = db.batch();
const shard_id = Math.floor(Math.random() * num_shards).toString();
const shard_ref = ref.collection('shards').doc(shard_id);
const commentRef = db.collection('comments').doc('comment');
batch.set(commentRef, { title: 'Comment title' });
batch.update(shard_ref, {
count: firebase.firestore.FieldValue.increment(1),
});
batch.commit();
For a document deletion you would decrement the counters, by using: firebase.firestore.FieldValue.increment(-1)
Finally, see in the doc how to query the counter value!