Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore - get specific fields from document

What I need:

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

  • Title
  • Content (texts or paragraphs)
  • Creation date
  • Owners (to share that article with other people and who can edit them like: https://firebase.google.com/docs/firestore/solutions/role-based-access)

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

  • Do you think it's better to do two queries (getArticle and getContent) at the same time and wait with Promise.all() instead of nesting the querys like I do?

  • Is there a better way to get the article and its content with one query or more efficiently? Some tips or ideas?

Thank you very much in advance!

like image 735
Garu Avatar asked Mar 26 '18 03:03

Garu


People also ask

Which function is used to fetch data from the firebase document?

The Get() function in Go unmarshals the data into a given data structure. Notice that we used the value event type in the example above, which reads the entire contents of a Firebase database reference, even if only one piece of data changed.

How do I aggregate data in firestore?

If you want to gain insight into properties of the collection as a whole, you will need aggregation over a collection. Cloud Firestore does not support native aggregation queries. However, you can use client-side transactions or Cloud Functions to easily maintain aggregate information about your data.


1 Answers

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')}.`); }); 
like image 86
abraham Avatar answered Oct 13 '22 18:10

abraham