- Get list of filenames in folder with Javascript
- 13 Answers 13
- How to get all documents from a collection in FaunaDB?
- Getting all documents from one collection in Firestore
- 13 Answers 13
- Is there a way to get all documents in a subcollection (Firestore)
- 2 Answers 2
- With Firebase Version 9 (Jan, 2022 Update):
Get list of filenames in folder with Javascript
My website is serving a lot of pictures from /assets/photos/ folder. How can I get a list of the files in that folder with Javascript?
What have you tried? And in what context do you want to retrieve the list of files. From the browser or from a server with node.js?
@Mike I doubt the browser choice really matters. The browser doesn’t have access to the list of files unless the server presents it.
13 Answers 13
The current code will give a list of all files in a folder, assuming it’s on the server side you want to list all files:
var fs = require('fs'); var files = fs.readdirSync('/assets/photos/');
Where does require() come from or is defined. Your code proiduces a «‘require’ is not defined» error. Have you tested your code? If so, have you maybe missed some important part referring to ‘require’?
@Apostolos As OP notes in the description, this needs to be server-side code. You can not run this in a browser. Running this script with Node.js does not throw any errors.
This is a good way but seems doesn’t answer the question directly. The simple answer is No, in JS from client side(browser) there is no direct way to get list of files in a folder/directory on server side.
No, Javascript doesn’t have access to the filesystem. Server side Javascript is a whole different story but I guess you don’t mean that.
@jtheletter The API is running on the server, so you’d use whatever stack you have running on your server. If that’s Node, it would be fs.readdir.
I write a file dir.php
var files = echo json_encode($out); ?>;
@2540625 that is php, not pure javascript. Despite you need php and it does not solve the issue of the author, it is still a pretty good solution if you have php.
Alternatively if you want to list all files, either use *.* or use scandir to preserve file extensions, $out = scandir(«.»); echo json_encode($out);
For getting the list of filenames in a specified folder, you can use:
fs.readdir(directory_path, callback_function)
This will return a list which you can parse by simple list indexing like file[0],file[1] , etc.
For client side files, you cannot get a list of files in a user’s local directory.
If the user has provided uploaded files, you can access them via their input element.
I made a different route for every file in a particular directory. Therefore, going to that path meant opening that file.
I called this function passing the list of filename in the directory __dirname/public/extracted and it created a different route for each filename which I was able to render on server side.
I use the following (stripped-down code) in Firefox 69.0 (on Ubuntu) to read a directory and show the image as part of a digital photo frame. The page is made in HTML, CSS, and JavaScript, and it is located on the same machine where I run the browser. The images are located on the same machine as well, so there is no viewing from «outside».
var directory = ; var xmlHttp = new XMLHttpRequest(); xmlHttp.open('GET', directory, false); // false for synchronous request xmlHttp.send(null); var ret = xmlHttp.responseText; var fileList = ret.split('\n'); for (i = 0; i < fileList.length; i++) < var fileinfo = fileList[i].split(' '); if (fileinfo[0] == '201:') < document.write(fileinfo[1] + "
"); document.write(''); > >
This requires the policy security.fileuri.strict_origin_policy to be disabled. This means it might not be a solution you want to use. In my case I deemed it ok.
How to get all documents from a collection in FaunaDB?
FaunaDB’s FQL language is quite similar to JavaScript (which helps a lot if you want to do conditional transactions etc).
In essence, FaunaDB also has a Map. Given that your index contains only one value that is the reference you can write this:
q.Map( q.Paginate(q.Match(q.Index('skus'))), q.Lambda(x => q.Get(x)) )
For this specific case, you actually do not need an index since each collection has a built-in default index to do a select all via the ‘Documents’ function.
q.Map( q.Paginate(q.Documents(q.Collection(''))), q.Lambda(x => q.Get(x)) )
Now in case the index that you are using returns multiple values (because you would want to sort on something other than ‘ref’) then you need to provide the same amount of parameters to the Lambda as the amount of values that were defined in the index. Let’s say my index has ts and ref in values because I want to sort them on time, then the query to get all values becomes:
q.Map( q.Paginate(q.Match(q.Index(''))), q.Lambda((ts, ref) => q.Get(ref)) )
Values are used for range queries/sorting but also define what the index returns
Coming back to your questions:
— Can I query for all documents in a single call?
Absolutely, I would advice you to do so. Note that the documents you will get are paginated automatically. You can set the page size by providing a parameter to paginate and will get back an ‘after’ or ‘before’ attribute in case the page is bigger. That after or before can be again presented to the Paginate function as a parameter to get a next or previous page: https://docs.fauna.com/fauna/current/api/fql/functions/paginate
— Could I make such a query without an index?
No, but you can use the built-in index as explained above. FaunaDB protects users from querying without an index. Since it is a scalable database that could contain massive data and is pay-as-you-go it’s a good idea to prevent users from shooting themselves in the foot :). Pagination and mandatory Indexes help to do that.
As to the why FQL is different. FQL is a language that is not declarative like many querying languages. Instead it’s procedural, you write exactly how you fetch data. That has advantages:
- By writing how data is retrieved you can exactly predict how a query behaves which is nice-to-have in a pay-as-you-go system.
- The same language can be used for security rules or complex conditional transactions (update certain entities or many entities ranging over different collections depending on certain conditions). It’s quite common in Fauna to write a query that does many things in one transaction.
- Our flavour of ‘stored procedures’ called User Defined Functions are just written in FQL and not another language.
Getting all documents from one collection in Firestore
Hi I’m starting with javascript and react-native and I’m trying to figure out this problem for hours now. Can someone explain me how to get all the documents from firestore collection ? I have been trying this:
async getMarkers() < const events = await firebase.firestore().collection('events').get() .then(querySnapshot => < querySnapshot.docs.map(doc =>< console.log('LOG 1', doc.data()); return doc.data(); >); >); console.log('LOG 2', events); return events; >
13 Answers 13
The example in the other answer is unnecessarily complex. This would be more straightforward, if all you want to do is return the raw data objects for each document in a query or collection:
Would this count towards one read for the quota, or would each document in the collection count as a read operation?
@Mentor The query will incur a read for every matched document, regardless of what you do with the snapshots in your code.
async getMarkers() < const events = await firebase.firestore().collection('events') events.get().then((querySnapshot) => < const tempDoc = querySnapshot.docs.map((doc) => < return < id: doc.id, . doc.data() >>) console.log(tempDoc) >) >
async getMarkers() < const events = await firebase.firestore().collection('events') events.get().then((querySnapshot) => < const tempDoc = [] querySnapshot.forEach((doc) =>< tempDoc.push(< id: doc.id, . doc.data() >) >) console.log(tempDoc) >) >
async getMarkers() < const markers = []; await firebase.firestore().collection('events').get() .then(querySnapshot => < querySnapshot.docs.forEach(doc =>< markers.push(doc.data()); >); >); return markers; >
if you need to include the key of the document in the response, another alternative is:
async getMarker() < const snapshot = await firebase.firestore().collection('events').get() const documents = []; snapshot.forEach(doc =>< const document = < [doc.id]: doc.data() >; documents.push(document); > return documents; >
import < collection, getDocs >from "firebase/firestore"; const querySnapshot = await getDocs(collection(db, "cities")); querySnapshot.forEach((doc) => < // doc.data() is never undefined for query doc snapshots console.log(doc.id, " =>", doc.data()); >);
However I am using the following (excuse the TypeScript):
import < collection, Firestore, getDocs, Query, QueryDocumentSnapshot, QuerySnapshot >from 'firebase/firestore' const q: Query = collection(db, 'videos') const querySnapshot: QuerySnapshot = await getDocs(q) const docs: QueryDocumentSnapshot[] = querySnapshot.docs const videos: IVideoProcessed[] = docs.map((doc: QueryDocumentSnapshot) => doc.data())
where db has the type Firestore
You could get the whole collection as an object, rather than array like this:
async function getMarker() < const snapshot = await firebase.firestore().collection('events').get() const collection = <>; snapshot.forEach(doc => < collection[doc.id] = doc.data(); >); return collection; >
That would give you a better representation of what’s in firestore. Nothing wrong with an array, just another option.
Two years late but I just began reading the Firestore documentation recently cover to cover for fun and found withConverter which I saw wasn’t posted in any of the above answers. Thus:
If you want to include ids and also use withConverter (Firestore’s version of ORMs, like ActiveRecord for Ruby on Rails, Entity Framework for .NET, etc), then this might be useful for you:
Somewhere in your project, you probably have your Event model properly defined. For example, something like:
Your model (in TypeScript ): ./models/Event.js
export class Event < constructor ( public id: string, public title: string, public datetime: Date ) >export const eventConverter = < toFirestore: function (event: Event) < return < // id: event.id, // Note! Not in ".data()" of the model! title: event.title, datetime: event.datetime >>, fromFirestore: function (snapshot: any, options: any) < const data = snapshot.data(options) const return new Event(id, data.title, data.datetime) >>
And then your client-side TypeScript code:
import < eventConverter >from './models/Event.js' . async function loadEvents () < const qs = await firebase.firestore().collection('events') .orderBy('datetime').limit(3) // Remember to limit return sizes! .withConverter(eventConverter).get() const events = qs.docs.map((doc: any) =>doc.data()) . >
Two interesting quirks of Firestore to notice (or at least, I thought were interesting):
- Your event.id is actually stored «one-level-up» in snapshot.id and not snapshot.data() .
- If you’re using TypeScript, the TS linter (or whatever it’s called) sadly isn’t smart enough to understand:
const events = qs.docs.map((doc: Event) => doc.data())
even though right above it you explicitly stated: .withConverter(eventConverter)
Which is why it needs to be doc: any .
(But! You will actually get Array back! (Not Array back.) That’s the entire point of withConverter . That way if you have any object methods (not shown here in this example), you can immediately use them.)
It makes sense to me but I guess I’ve gotten so greedy/spoiled that I just kinda expect my VS Code, ESLint, and the TS Watcher to literally do everything for me. 😇 Oh well.
Is there a way to get all documents in a subcollection (Firestore)
I’m having difficulties querying all documents inside a subcollection in my Firestore database. (I am using Node.js) My goal is to get all the data from every document inside the subcollection named favorites My database structure looks like this. I looked at the documentation at https://firebase.google.com/docs/firestore/query-data/get-data but without any result how to solve the problem. My query looks like this right now:
exports.getAllFavoritePodcasts = (req, res) => < db.collection('users') .doc(req.user.userId) .collection('favorites') .then(snapshot => < snapshot.forEach(doc =>< console.log(doc.id, '=>', doc.data()); >); >) .catch(err => < console.log('Error getting documents', err); >); >
I’m not familiar with firebase but aren’t you missing .get() before then -> db.collection(. ).doc(. ).collection(. ).get().then
2 Answers 2
With Firebase Version 9 (Jan, 2022 Update):
If subcollection(subcoll) contains 3 documents(doc1, doc2, doc3) like below:
coll > doc > subcoll > doc1 > field1: "value1", field2: "value2" doc2 > field1: "value1", field2: "value2" doc3 > field1: "v1", field2: "v2"
You can get all 3 documents(doc1, doc2, doc3) of subcollection(subcoll) with the code below:
import < getDocs, collection >from "firebase/firestore"; const docsSnap = await getDocs(collection(db,"coll/doc/subcoll")); docsSnap.forEach((doc) => < console.log(doc.data()); // "doc1", "doc2" and "doc3" >);
Without forEach() method to get all 3 documents(doc1, doc2, doc3) of subcollection(subcoll) below:
import < getDocs, collection >from "firebase/firestore"; const docsSnap = await getDocs(collection(db, "coll/doc/subcoll")); console.log(docsSnap.docs[0].data()); // "doc1" console.log(docsSnap.docs[1].data()); // "doc2" console.log(docsSnap.docs[2].data()); // "doc3"
In addition, you can get 2 documents(doc1, doc2) of subcollection(subcoll) with while below:
import < query, collection, where, getDocs >from "firebase/firestore"; const q = query(collection(db, "coll/doc/subcoll"), where("field1", "==", "value1")); const docsSnap = await getDocs(q); docsSnap.forEach((doc) => < console.log(doc.data()); // "doc1" and "doc2" >);
Without forEach() method to get 2 documents(doc1, doc2) of subcollection(subcoll) with while below:
import < query, collection, where, getDocs >from "firebase/firestore"; const q = query(collection(db, "coll/doc/subcoll"), where("field1", "==", "value1")); const docsSnap = await getDocs(q); console.log(docsSnap.docs[0].data()); // "doc1" console.log(docsSnap.docs[1].data()); // "doc2"
Again, in addition, you can get only one specific document(doc3) of subcollection(subcoll) with the code below:
import < getDoc, doc >from "firebase/firestore"; const docSnap = await getDoc(doc(db, "coll/doc/subcoll/doc3")); console.log(docSnap.data()); // "doc3"