This week I was tasked with learning about Firebase and setting up an application to interact with the Firestore Realtime Database for storage.
I don't want to repeat all the details of the experience because I basically implemented the instructions found in the Firebase documentation and the Firebase React Tutorial by Robin Weiruch.
This is how I implemented using the fetch API to retrieve the data.
1. Connect to the Firebase Services
Implementing the connection to Firebase services and the functions necessary to retrieve and mutate the data can be neatly encapsulated in a class. I created mine in the file /src/Firebase/firebase.js
.
Be sure to add the Firebase npm modules.
yarn add Firebase
I included the necessary modules.
import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
The configuration variable details were provided when I set up my Firebase project. I just copied and pasted mine. I've included it below, with a couple of specifics missing.
var firebaseConfig = {
apiKey: "--------------------------------",
authDomain: "myproject.firebaseapp.com",
databaseURL: "https://myproject.firebaseio.com",
projectId: "myproject",
storageBucket: "myproject.appspot.com",
messagingSenderId: "748127105525",
appId: "1:748127105525:web:983360bf4adfabfa3bf0bc",
measurementId: "G-6ZWGLLZQ1Y"
};
The class will connect to the services in the constructor.
class Firebase {
constructor() {
app.initializeApp(firebaseConfig);
this.auth = app.auth();
this.db = app.firestore();
}
...
}
export default Firebase;
2. Code the Read Method
Reading and writing are handled through the methods provided in the Firebase library. For example, reading from the users collection can be done using app.firestore().collection("users").get()
. Writing can be done using similar methods, such as app.firestore().collection("users").doc(_key).set(_profileObject)
.
As you might expect, these methods are executed asynchronously. I wrapped the read method so that I could include a callback for handling the data once it's retrieved.
class Firebase {
constructor() {
app.initializeApp(firebaseConfig);
this.auth = app.auth();
this.db = app.firestore();
}
...
doGetAllUsers = (callback) => {
this.db
.collection("users")
.get()
.then(callback)
}
...
}
export default Firebase;
3. Create a Context for Firebase Services
To make use of the Firebase connection across my application, I included useContext.
I created the file src/Firebase/context.js in my Firebase directory.
import React from 'react';
const FirebaseContext = React.createContext(null);
FirebaseContext.displayName = "Firebase"
export default FirebaseContext;
Then, I combined the exports for context and Firebase in src/Firebase/index.js
import FirebaseContext from './context';
import Firebase from './firebase';
export default Firebase;
export { FirebaseContext };
My project's index.js wraps the <App />
component with the Context Provider.
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import Firebase, { FirebaseContext } from './components/Firebase';
ReactDOM.render(
<FirebaseContext.Provider value={new Firebase()}>
<App />
</FirebaseContext.Provider>,
document.getElementById("root")
);
4. Use React Hooks to Store the Data
Now that the Firebase class is ready to go, let's make use of it within a React component.
I included the appropriate React hooks tools as well as the FirebaseContext.
import React, { useContext, useEffect, useState } from "react";
import { FirebaseContext } from "../../components/Firebase";
export default (props) => {
...
}
I assigned the identifier firebase to the context for my Firebase class. This allows me to access the connected Firebase services within my component.
Then I created a state variable docs to hold the users collection records.
Finally, I invoked the firebase.doGetAllUsers()
method I wrote earlier, passing it a callback function to store the data in this component's state.
export default (props) => {
const firebase = useContext(FirebaseContext);
const [docs, setDocs] = useState([]);
// Pass a callback to handle the data.
useEffect(
() =>
firebaseb.doGetAllUsers((snapShot) => {
const tempDocs = [];
snapShot.forEach((doc) => {
tempDocs.push(doc.data());
});
setDocs([...tempDocs]);
}),
[fb]
);
...
}
** It's important to note that the array [fb]
was passed to useEffect as the second parameter, which is set call the function only when certain values have changed. In this case, the value of fb
won't change, and the function will only be executed when the component mounts.
That should do it. The data from the users collection will now be stored in the state variable and can be rendered by the component. For example:
<div>
<h2>Users</h2>
{docs.length > 0 ? (
docs.map((doc, i) => (
<div key={i}>
<p>
{doc.firstName} {doc.lastName}, {doc.city}
</p>
</div>
))
) : (
<div>
<p>No users found.</p>
</div>
)}
</div>
This is what I learned. I hope this helps others attempting to stand up a React app with Firestore Realtime Database. As this was my first implementation, I welcome any suggestions on improvement.
Happy coding!
Top comments (0)