Querying Firebase Realtime database with React and Redux
Tags: firebase, googlecloud, react, redux
Published: 2021-01-21 16:49:06

Recently, I was tasked with putting together an art portfolio web application. I decided during that time that I wanted to learn and get some exposure to backend as a service(BaaS). There are 2 major cloud backend services out there. There is AWS Amplify and Google Firebase. After some experimentation, I found that I wanted to use Google Firebase because it was geared more toward small and medium web applications. The authentication is easier to understand and it contains many of the same features as AWS Amplify. For instance, cloud storage is available for both and I've used both AWS S3 and Google Firebase storage. They operate similarly. 

One feature I really like about Google Firebase is their Realtime database. The term "Realtime" is certainly appealing given the fact that I was using Ruby on Rails and couldn't get real time data without installing and figuring out GraphQL and Appollo. Google Firebase uses a NoSQL database for the Realtime database and at first, learning it was a little intimidating, but over time, I found it to be easier to use than Rails as an API. Rails as an API definitely has many good features when used with PostgreSQL in that they have ORM built-in so having a relational database has its pros. 

For my art portfolio web application, I didn't necessarily need this unless it came to having my e-commerce feature (which I'm still building).

In this post, I will be focusing on what queries look like in Google Cloud Firebase's Realtime database. When using React, make sure you have your import setup like so:

```javascript
import firebase from "firebase/app";
```
So to start a query, you must create a reference to the database that you desire. For my example, I am creating a reference to my arts section of my database. It looks like this:

```javascript
let artsRef = firebase.database().ref('arts/')
```
My database looks like this:

![Realtime database picture](https://dev-to-uploads.s3.amazonaws.com/i/vmpqpdavvk7bsxhhnkan.PNG)

For my first example, I want to get this data, push it up to Redux, and render. I create my function inside useEffect. Here is my function:

```javascript
useEffect(() => {
        function getData() {
            
        
            let artsRef = firebase.database().ref('arts/')
            
            return artsRef.once('value', (snapshot) => {
                
                const data = snapshot.val()
                
                dispatch({type: 'GET_ARTS', payload: data})
            })
            
        }
        getData()
        
    },[dispatch])
```
Notice I call on the "once" function. This will only read the data once and get what's called a snapshot. After I get the snapshot. I call on snapshot.val() to get the associated data that I'm querying. After I have the data, I call on the artsReducer to load the data from my Redux store. Putting the data in Redux is simple. Here is what it looks like:

```javascript
export function artsReducer(state = { arts: [], requesting: false, loaded: false}, action) {
    let art;
    let arts;
    switch(action.type) {

        case 'GET_ARTS':
            //debugger
            return {
                ...state,
                arts: action.payload,
                requesting: false,
                loaded: true
            }

        default:
            return state
    }
}
```
This will update my Redux store with all the art objects from my database. After getting the data, it is a simple React render call which I won't cover in this post. Here is what my data looks like in Redux:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0rt4gfv3y815w97b79p2.PNG)

So for my last example, I want to do something a little more involved. What if my user wants to see all my art that is $100? This can also be done with a simple query to the database. 
In this example, I 

```javascript
    useEffect(() => {
        function getData() {
        let artsRef = firebase.database().ref('arts/').orderByChild('price').equalTo('100').limitToFirst(3)
            
            artsRef.once('value', snap => {
                
                const data= snap.val()
                
                dispatch({type: 'GET_ARTS', payload: data})
                
            })
        getData()
    }, [artRoute, dispatch])
```
Notice in this example, in order to get the proper price, I call on "orderByChild" and this will order by the child reference in my database called "price". I call on "equalTo" to get the art that is priced at $100 and I limit my results to the first 3 results with "limitToFirst".

All of the database queries can be found here:
[Working with lists of data](https://firebase.google.com/docs/database/web/lists-of-data)

Using the Firebase Realtime database is very powerful. It gets the data immediately and is easy to work with. In future posts, I will cover how to get data stored in cloud storage. Until then, happy coding!