web-dev-qa-db-fra.com

Firestore - récupère des champs spécifiques du document

Ce dont j'ai besoin:

Je souhaite enregistrer des articles ou des notes dans Firestore avec leurs champs respectifs:

Mais lorsque je montre la liste des articles, je n'ai pas besoin du champ "contenu" (pour économiser la bande passante). J'ai lu que (peut-être que je me trompe), il n'est pas possible de faire une requête pour obtenir uniquement des champs spécifiques d'un document avec Firestore.

S'il était normal que SQL obtienne des colonnes spécifiques à partir d'articles (sans son contenu), cela ressemblerait à quelque chose comme:

SELECT title, creation_date, ...
FROM table_name;

J'ai donc choisi de séparer le contenu de deux collections au niveau racine (pour plus de souplesse et d'évolutivité). 


Ma structure actuelle:

Collection d'articles:

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

Collection de contenu:

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

Pour obtenir la liste des articles en temps réel:

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
  })

Pour afficher dans une autre vue et obtenir l'article complet avec son contenu:

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
      }
    })
  } 
})

Mes questions

  • Pensez-vous qu'il est préférable de faire deux requêtes (getArticle et getContent) en même temps et d'attendre avec Promise.all () au lieu d'imbriquer les requêtes comme je le fais?

  • Existe-t-il un meilleur moyen d'obtenir l'article et son contenu en une seule requête ou plus efficacement? Quelques astuces ou idées?

Merci beaucoup d'avance!

8
BlackCode

Aucune de ces approches n’est meilleure que l’autre. Mais il y a quelques différences clés.

  1. Lorsque vous imbriquez les lectures, la deuxième lecture ne commence qu'une fois la première lecture terminée. Lorsque vous utilisez Promise.all(), les deux lectures commencent en même temps et peuvent donc (partiellement) être exécutées en parallèle.

  2. D'autre part: lorsque vous utilisez Promise.all(), votre gestionnaire d'achèvement (le code que vous exécutez dans then()) ne s'exécutera pas tant que les deux documents ne seront pas chargés. Si vous imbriquez les appels, vous pouvez mettre à jour l'interface utilisateur après le chargement du premier document.

En fin de compte, les différences seront probablement minimes. Mais comme ils peuvent être importants pour votre cas d'utilisation, mesurez les résultats et voyez ce qui vous convient le mieux.

4
Frank van Puffelen

Selon la documentation Firestore Query.select , vous devriez pouvoir sélectionner les champs de votre choix.

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')}.`);
});
1
abraham

Firebase Hosting serait votre meilleur choix pour le contenu statique tel que les articles. Si vous regardez AMP-HTML par exemple, ils plaident fortement en faveur de chargements de page ultra-rapides et mettent en évidence les avantages de la mise en cache Edge. L’hébergement Firebase est annoncé pour prendre également en charge la mise en cache Edge globale .

Firestore et Firebase Realtime Database sont des moteurs de base de données. Ce ne sont pas le bon outil pour servir des articles.

0
Ron Royston