Garu
Garu

Reputation: 1179

Firestore - get specific fields from document

What I need:

I want to save articles or notes in Firestore with their respective fields:

But when I show the list of articles I don't need the "content" field (to save bandwidth). I've read that (maybe I'm wrong), it is not possible to make a query to get only specific fields from a document with Firestore.

If it were normal SQL to obtain specific columns from articles (without its content) It would be something like:

SELECT title, creation_date, ...
FROM table_name;

So I've opted to separate the content for two root-level collections (for flexibility and scalability)


My current structure:

Articles collection:

  - `articles` [collection]
    - `ARTICLE_ID` [document]
      - `creatorId` [field]
      - `title` [field]
      - `date` [field]
      - `owners` [obj field]
          - {user1_id}: true
          - {user2_id}: true
          ...

Contents collection:

  - `contents` [collection]
    - `{ARTICLE_ID}` [document]
      - `content` [field]

To get articles list in realtime:

firebase.firestore().collection('articles')
  .where(`owners.${user.uid}`, '==', true)
  .onSnapshot(querySnapshot => {
    const articles = []
    querySnapshot.forEach((doc) => {
      articles.push({
        id: doc.id,
        ...doc.data()
      })
    })
    // do something with articles array
  })

To show in another view and get the entire article with its content:

const db = firebase.firestore()
const articleRef = db.collection('articles').doc(articleId)
const contentRef = db.collection('contents').doc(articleId) // same Id as article

articleRef.get().then(articleDoc => {
  if (articleDoc.exists) {
    contentRef.get().then(contentDoc => {
      if (contentDoc.exists) {
        const article = {
          ...articleDoc.data(),
          ...contentDoc.data()
        }
        // full article obj
      }
    })
  } 
})

My questions

Thank you very much in advance!

Upvotes: 56

Views: 61862

Answers (4)

Michael JC
Michael JC

Reputation: 51

In order to output a single field from a Firestore document (version 9) - for example the 'title' in the articles collection you can use the following code snippet:

const q = query(collection(db, 'articles'))
let results = [];
await getDocs(q);
results = getLocation.docs.map((doc) => doc.data()['title']);
results.sort()

The results array will contain only the title field, sorted alphabetically (Note you have to reference the Firestore db and import 'getDocs', 'query' and 'collection' modules from Firestore)

Upvotes: -4

abraham
abraham

Reputation: 47833

According to the Firestore Query.select documentation you should be able to select the fields you want.

let collectionRef = firestore.collection('col');
let documentRef = collectionRef.doc('doc');

return documentRef.set({x:10, y:5}).then(() => {
  return collectionRef.where('x', '>', 5).select('y').get();
}).then((res) => {
  console.log(`y is ${res.docs[0].get('y')}.`);
});

Upvotes: 32

Frank van Puffelen
Frank van Puffelen

Reputation: 598817

Neither approach is pertinently better than the other. But there are a few key differences.

  1. When you nest the reads, the second read only starts after the first read has completed. When you use Promise.all() both reads start at the same time, so can (partially) run in parallel.

  2. On the other hand: when you use Promise.all() your completion handler (the code you run in then()) won't execute until both documents have loaded. If you nest the calls, you can update the UI after just the first document has loaded.

In the end, the differences are likely to be small. But since they may be significant to your use-case, measure the results and see what works best for you.

Upvotes: 11

Ronnie Smith
Ronnie Smith

Reputation: 18565

Firebase Hosting would be your best bet for static content such as articles. If you look at AMP-HTML for example, they strongly make the case for ultra-fast page loads and highlight benefits of edge caching. Firebase hosting is advertised to also support global edge caching.

Firestore and Firebase Realtime Database are database engines. These are not the proper tool for serving up articles.

Upvotes: -4

Related Questions