roger-melo-treinamentos / curso-de-js-roger-melo

Repositório de informações do CJRM
493 stars 172 forks source link

Resumo da Aula Aula 01-13 da etapa 15 - Lendo dados do Firestore #6126

Closed Jansen-Muniz closed 1 year ago

Jansen-Muniz commented 1 year ago
import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.0.1/firebase-app.js'
import { getFirestore, collection, getDocs } from 'https://www.gstatic.com/firebasejs/9.0.1/firebase-firestore.js'

const firebaseConfig = {
  apiKey: 'AIzaSyDx-PMbY38ljaIT4jUZqVAgHrrTZ5hbzTE',
  authDomain: 'testing-firebase-bda60.firebaseapp.com',
  projectId: 'testing-firebase-bda60',
  storageBucket: 'testing-firebase-bda60.appspot.com',
  messagingSenderId: '915568476861',
  appId: '1:915568476861:web:79776b07329cb5e6b5add4',
  measurementId: 'G-PHNNKE2B2K'
}

/*
  Como obter e ler no frontend os dados que o banco de dados está armazenando
*/
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)

/*
Como a const db está armazendo a referencia do banco de dados, através 
dela e das funções importadas do firestore, posso obter os documents do collection games. 

Como poderiam haver múltiplos collections no banco, na hora de obter 
um collection, preciso especificar qual collection quero obter.
*/

//Obter todos os documents do collection games:

//1) obter a referencia do collection games

/*
  Invocar uma função chamada collecion. 
  Função que retorna a referencia de um collection
  Recebe dois valores como argumento:

    - O primeiro é referencia da const db - referencia do banco de dados no firestore
    - O segundo é o nome do collection a ser consultado, que é o games.

  A funcão collection precisa ser importada do SDK do firestore.
  Como esse segundo import 
- import { getFirestore } from 'https://www.gstatic.com/firebasejs/9.0.1/firebase-firestore.js' 
- é o que está sendo importado funções do SDK do firestore, dentro das chaves, 
depois da importação da getFirestore, será importado a collection - import { getFirestore, collection }... - 
*/

console.log(collection(db, 'games'))

/* 
No console é exibido um objeto que representa o collection games, com uma propriedade 
type que armazena collection e uma propriedade id que armazena games.
*/

/*
 Agora que obtive a referencia do collection games, posso, 
obter os documents dele, adicionar documents nele ou remover documents dele.  
*/

/*
 Como serão obtidos os documents do collection, será usada uma função do SDK do firestore chamada getDocs.

 Para importar a getDocs:
  - import { getFirestore, collection, getDocs }...

 A getDocs para trazer os documents vai executar uma query, uma consulta 
no banco, que é uma operação assíncrona, um request e vai retornar uma promise com um querySnapshot.
*/

//Para obter a promise que a getDocs retorna:  

console.log(getDocs(collection(db, 'games')))

/*
  O console exibe a promise que a getDocs retornou:

  Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Nu

[[PromiseState]]: "fulfilled" - indica que o request foi completado com sucesso.
*/

//Acessar o valor que a promise está encapsulando

/*
 Se o request for completado com sucesso, o callback do then vai receber por parâmetro um
 querySnapshot - o querySnapshot é uma representação do collection games no momento em que o request foi 
 executado.
*/

getDocs(collection(db, 'games'))
  .then(querySnapshot => {
    console.log(querySnapshot)
  }) 
  .catch(console.log)

image

Snapshot do collection games

//Formas de obter os documents de um collection no firestore

//Primeira forma: Usando forEach

getDocs(collection(db, 'games'))
   .then(querySnapshot => {
     /*
       O callback inserido como argumento do forEach, recebe por parâmetro cada document
       desse querySnapshot
     */
      querySnapshot.forEach(doc => console.log(doc))
      /*
        Cada doc, contém um método data que retorna os dados do document:
        createdAt, developmentBy, title
      */
   })
   .catch(console.log)
//Para inserir os dados de cada doc no console, é preciso encadear no doc a invocação do data()

getDocs(collection(db, 'games'))
   .then(querySnapshot => {
    querySnapshot.forEach(doc => console.log(doc.data()))
    //Os documents que o collection games contem
    //{developedBy: 'naughty dog', createdAt: st, title: 'the last of us(part II)'}
    //{title: 'hades', createdAt: st, developedBy: 'super giant games'}
   })
   .catch()

/*
 O problema dessa abordagem é que querySnapshot não é um array, 
 querySnapshot é um objeto
*/
//Segunda forma

getDocs(collection(db, 'games'))
   .then(querySnapshot => {
    //console.log(querySnapshot)
    //Tem uma propriedade docs, que é um array com todos os documents do querySnapshot
    //Para exibir os documents no console
    querySnapshot.docs.forEach(doc => console.log(doc.data()))//Nessa expressão posso usar qualquer método de array
    //{title: 'the last of us(part II)', createdAt: st, developedBy: 'naughty dog'}
    //{title: 'hades', developedBy: 'super giant games', createdAt: st}
   })
   .catch(console.log)
//Inserir na tela as informações dos documents

getDocs(collection(db, 'games'))
   .then(querySnapshot => {
    const gamesLis = querySnapshot.docs.reduce((acc, doc) => {
      acc += `<li>${doc.data().title}</li>`
      return acc
    }, '')

    const gamesList = document.querySelector('[data-js="games-list"]')
    gamesList.innerHTML += gamesLis
   })
   .catch(console.log)
/*
   Quando a aplicação for carregada, só os jogos que vieram do firestore 
   sejam exibidos na ul e exibir também os valores dos campos developedBy e 
   createdAt
*/

/*
  Para exibir na tela os valores dos campos developedBy e createdAt
*/
getDocs(collection(db, 'games'))
   .then(querySnapshot => {
    const gamesLis = querySnapshot.docs.reduce((acc, doc) => {
      const { title, developedBy, createdAt } = doc.data()

      acc += `<li class="my-4">
        <h5>${title}</h5>

        <ul>
          <li>Desenvolvido por ${developedBy}</li>
          <li>Adicionado no banco em ${createdAt.toDate()}</li>
        </ul>
      </li>`

      return acc
    }, '')

    const gamesList = document.querySelector('[data-js="games-list"]')
    gamesList.innerHTML = gamesLis
  })
   .catch(console.log)

   /*
    O método toDate() converte um objeto timestamp do firestore para um objeto de 
    data JS e retorna esse objeto de data JS
    O firebase tem um objeto de data diferente porque um timestamp do firebase usa 
    nanosegundos para representar o tempo.
   */
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  <link rel="stylesheet" href="./style.css">
  <title>Lendo dados do Firestore</title>
</head>
<body>
  <div class="container text-white my-5">
    <h2>Games</h2>

    <ul data-js="games-list">
      <!-- <li>Animal Crossing: New Horizons</li>
      <li>Final Fantasy VII Remake</li> -->
    </ul>

    <form>
      <label for="game">Adicionar game</label>

      <div class="input-group">
        <input class="form-control bg-transparent text-white" type="text" name="game" placeholder="Ex: Ghost of Tsushima" required autofocus>
        <input class="btn btn-primary" type="submit" value="Adicionar">
      </div>
    </form>
  </div>
  <script type="module" src="./app.js"></script>
</body>
</html>
body {
  background-color: #212529;
}
MivlaM commented 1 year ago

Excelente @Jansen-Muniz , rumo à fluência! 🎯