Retrieving Data from Firestore
Once Firestore is initialized, it is possible to retrieve data from the Firestore database. Data can be retrieved by a collection of documents or by one document at a time.
Collection
When retrieving Firestore collection from within a React component, start by importing the collection
, query
, and onSnapshot
method from the firebase/firestore
library and the db
variable from the src/db.js
. Also, import the useState
and useEffect
methods from the react
library. Create a state variable to hold the data from the Firestore database and call the useEffect
method to make the data request.
// src/routes/Restaurants.jsx
import { useState, useEffect } from 'react'
import { collection, query, onSnapshot } from 'firebase/firestore'
import db from '../db.js'
function Restaurants () {
const [restaurants, setRestaurants] = useState([])
useEffect(() => {
}, [])
}
From within the useEffect
method, create a collection
and a query
. Then call the onSnapshot
method. The onSnapshot
method takes two arguments, the query and a callback function. The callback function receives an argument containing the snapshot of the entire Firestore collection. A data
variable should be created and set to an empty array to serve as a temporary container for the snapshot data. Then using the snapshot and the forEach
method, the data of each document is added to the temporary array. Finally, the state variable is updated with the value of the temporary array.
// src/routes/Restaurants.jsx
import { useState, useEffect } from 'react'
import { collection, query, onSnapshot } from 'firebase/firestore'
import db from '../db.js'
function Restaurants () {
const [restaurants, setRestaurants] = useState([])
useEffect(() => {
// create collection using the database connection and collection id
const c = collection(db, 'restaurants')
// create a query using the collection
const q = query(c);
// onSnapshot includes realtime updates
const unsubscribe = onSnapshot(q, (snapshot) => {
const data = []
snapshot.forEach((doc) => data.push({
id: doc.id,
name: doc.data().name,
city: doc.data().city
}))
setRestaurants(data)
});
}, [])
}
Document
When using Firestore to retrieve a document, begin by importing the doc
and getDoc
method from the firebase/firestore
library and the db
variable from the src/db.js
. Also, import the useState
and useEffect
methods from the react
library. Create a state variable to hold the data from the Firestore docuement and call the useEffect
method to make the data request.
// src/routes/Restaurant
import { useState, useEffect } from 'react'
import { doc, getDoc } from 'firebase/firestore'
import db from '../db.js'
// document id
const id = '12345'
function Restaurant () {
const [restaurant, setRestaurant] = useState({
name: '',
city: ''
})
useEffect(() => {
}, [])
return (...)
}
As like when retrieving a collection, data properties and any necessary props should be added to the single file component. Then the created
lifecycle hook can be used to request the document data. Finally, the getDoc
method will be called to retrieve the specified document from within the' created' lifecycle hook. However, because the getDoc
method returns a promise, async
and await
should be used.
From within the useEffect
callback function, create a reference to the desired document using the doc
method. This will require the database connect (db
), the collection id, and the document id. Next, call the getDoc
method using the document reference. The getDoc
method returns a promise. Once the promise is fulfilled the state variable can be updated with data from the resulting document. Except for the document's id, all document data must be retrieved using the data
method.
NOTE
The callback function of the useEffect
method cannot be preceded by the async
keyword. Therefore, students are encouraged to use the then
method instead of async
and await
.
// src/routes/Restaurant
import { useState, useEffect } from 'react'
import { doc, getDoc } from 'firebase/firestore'
import db from '../db.js'
// document id
const id = '12345'
function Restaurant () {
const [restaurant, setRestaurant] = useState({
name: '',
city: ''
})
useEffect(() => {
getDoc(doc(db, 'restaurants', id))
.then(document => {
if (document.exists()) {
setRestaurant({
name: document.data().name,
city: document.data().city
})
}
})
}, [])
return (...)
}