React Learnings from 2018: Data Persistence with Firebase
Published: 2020-11-03 10:42:24

---
title: React Learnings from 2018: Data Persistence with Firebase
published: true
description: 
tags: 
//cover_image: https://direct_url_to_image.jpg
---

This is a post from 2018 for hooking up Firebase with React. Using knowledge gleaned from [Wes Bos' React for Beginners](www.reactforbeginners.com). Its probably outdated but I wanted it on my blog for the sake of reference.

We have made a fairly clever CRUD app, where state and props are used to react and update the UI accordingly. So far our React apps have been volitile, 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!)

# Introducing Firebase

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 that.

Then go to [firebase.google.com](firebase.google.com) and select Add Project.

Give it a unique name and then create it, which will take abotu 30 seconds.

You will be presented with a landing page wit 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 dont 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 wouldnt want to do this obviously, but it will make life easier for now.

**Connection details**
Now we have an empty database, how do we get it to 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.

Kepe 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

We want to create a file called base.js' in our `src` directory which will handle the database connection

It requires the following imports:

1. Re-base, a helpful library to  mirror our state
`import Rebase from "re-base" `

2. 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:

```js
const firebaseApp = firebase.initializeApp({
    apiKey: "blah",
    authDomain: "blah",
    databaseURL: "blah",
})
```

Secondly we need to setup our *Rebase bindings*:

`const base = Rebase.createClass(firebaseApp.database())`

Lastly we need to export firebaseApp as a named export: `export {firebaseApp}`

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:

```js
 componentDidmount(){ 
    this.ref=base.syncState(`$this.props.match.params.storeId/groceries`, {
         context: this,
         state: "groceries"
    })
}
```

**Lets explain that a little**

`this.ref` - alows 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, `context` and `state`

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](https://github.com/tylermcginnis/re-base)

Thats it! It might look gnarly but thats 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:

```js
componentWillUnmount(){
    base.removeBinding(this.ref);
}
```

...and thats why we needed `this.ref`!

## Final Thoughts

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.