React for Beginners #9 — React App Persistence with Firebase
This is part 9 of my React Learning series. Using knowledge gleaned from Wes Bos’ React for Beginners.
We have made a fairly clever CRUD app, where state and props are used to react and update the visuals accordingly. So far our React apps have been volatile, as in if we refresh the page or close the browser we lose what we did. What would be great if there was an easy way of mirroring our state to a database. Lucky* for us then, there is!
(*By luck I actually mean thanks to all the awesome people who build such things for the rest of us to use!)
Firebase is Real-time database from Google. It uses Websockets which allows real time changes as opposed to having to refresh via Ajax or somesuch.
First thing we need to get up Firebase, which requires a Google account. I’m going to assume you are cool with sorting that out.
Then go to http://firebase.google.com and select Add Project.
Give it a unique name and then create it, which will take about 30 seconds.
You will be presented with a landing page with all sorts of toys, analytics, authentication, etc. That is quite a few blog posts worth but for now, lets go see about a Database… by clicking Database.
Choosing a Database At time of writing there is Real-time Database and a beta Cloud Firestore as database options. Let’s go with
Real-time Database as we don’t need anything fancy right now.
Security Rules By default, the database will want to start in
locked mode, which stops any read or writes. For now we can use
test mode which allows all reads and writes. In a production App we wouldn’t want to do this obviously, but it will make life easier for now.
Connection details Now we have an empty database, how do we work with it in our code? From the
Project Overview link, you should see a
Add Firebase to your Web App Button which will generate a code snippet we can use.
Keep that code handy for a second, we first need a file in our app that lets us use that information…
All about the base.js
As we link keeping this modular, we want to create a file called base.js’ in our
src directory which will handle the database connection
It requires the following imports/packages. Install them via npm if you don’t already have them:
- Re-base, a helpful library to mirror our state
import Rebase from "re-base"
- Firebase, the main library for Firebase to Databasify (I am making that a word) any other data other than state:
import firebase from "firebase"
To begin using firebase we need to use the
initializeApp method with the
apiKey, authDomain and DatabaseURL as properties. Which we can grab from that code snippet I told you to hold onto about a minute ago.
We can put that into a const like so:
Secondly we need to setup our Rebase bindings:
const base = Rebase.createClass(firebaseApp.database())
Lastly we need to export firebaseApp as a named export:
And base as our default:
export default base;
Getting our state to mirror into our Database
Head on over to our App.js and import our base.js:
import base from '../base
Here we need to use a
lifecycle method called
componentDidMount. This performs a set of instructions when the component is first loaded onto the page. There is alot of lifecycle methods and worth discussing another time. But for now lets roll with the following method:
Lets explain that a little
this.ref - allows us to reference this particular binding should we need to do something with it later.
syncState - A rebase method. A two way binding between any property on your component's state adn any endpoint in Firebase. It takes an string argument to specify an endpoint, i.e. to which bit of the database to sync to. Plus an object of further options,
For the endpoint we want to use the store we generated. We got the store ID from props, and is actually provided by React router, and the
/groceries makes sure we only sync that part of the state.
context - The component we want to sync the state for.
state - The property you want to sync with Firebase.
It’s a fair bit to take in, but don’t be afraid to read the docs for Re-base
That’s it! It might look gnarly but that’s a short amount of code to quite a powerful action. If we browse to the database on the firebase console, we should see the state/groceries mirrored there. Plus, as it is a two way sync, we can change values on either end and see the change replicate near instantly!
Doing some cleanup
There is a slight gotcha…
Everytime the component mounts, we set up the sync for a given store. However we never stop it not syncing, it will quite happily continue to watch for changes for that store till the end of time. Or till we run out of memory…
To stop this, we can use another lifecycle method,
componentWillUnmount. Which runs whenever the component is closed for whatever reason. We can use that to remove our binding:
…and that’s why we needed
I have used Mongo previously, Firebase has a pretty slick way of working too. I think there is a definite series on other Firebase uses worth doing. Probably will forget though…