Using Firebase’s Realtime Database with React to Create a Real Time Music Web Application

Luis Miguel Rincon
5 min readMar 19, 2018

--

So I recently created a web application with a great friend of mine, Noelle Laureano (Check her out. She’s a coding wizard and has a great article on Firebase as well.). We had an idea for a web application where we could listen to a song with someone at the same time from anywhere. Thus, came The Listening Room. We knew we needed some sort of technology that would enable us to have a constant communication with a server to let us hear a song at the same time. Our journey took us to this really cool technology from Google called, Firebase.

Firebase essentially handles all the details of your apps backend infrastructure. It’s a cloud-hosted noSQL database that allows you to store, sync, and query data in real-time between users. This Realtime Database comes with mobile and web SDKs so you can build applications without the need of creating your own servers. You can invoke code that responds to events in your database using Firebase’s Cloud Functions. It’s literally 🔥!

So, I’ll briefly go over how we managed to play a song in realtime since its the apps main functionality. We used React to create this application as well. We knew we wanted users to choose a specific song so we decided to allow users to upload any mp3 of their choice from their personal computer. So we needed to somehow store that users mp3 to a storage. Once again, Firebase to the rescue. Firebase has a solution for a powerful and effective storage service. Cloud Storage, as its called, is for developers who need to store and save user generated content such as images, videos, or in our case, music or mp3 files. Now that we have a place to store this mp3 file, we need to access this file in our storage. This is when we started to think about how we could get the actual audio of the mp3 to play and we quickly realized that once this mp3 file was saved to the storage, it also created a download URL in which we could go to that URL and the song would play.

Who doesn’t love Whitney Houston?

In the code snippet above we created a function that handled the uploading event when the user uploaded the mp3. We then store that uploaded mp3 file in a variable called “file” and create a reference to our Firebase Cloud storage as shown on line 88. We then “put” the file in the database which is an asynchronous action. Now that we have the mp3 file in our Firebase storage we need that download URL we mentioned earlier in order to put it in an audio HTML tag which allows you to play music from a source. For example:

<audio src={"download URL created from Firebase Storage goes in here"} />

We then reference our storage again where our music folder is holding all our mp3’s. From there we access the specific “child” of that folder by passing in the mp3 filename we saved earlier in line 86 and pass it into the function and invoke that with getMetadata(). This function is also asynchronous since its touching our storage which is basically like a database. We “.then” off of that and that gives us back a promise containing an array of a bunch of metadata from that mp3 file. In our case, we’re only interested in the download URL which is the first element in that array thats given to us. Now that we FINALLY have that download URL we were digging around for, its time to push it to our Firebase Realtime Database.

Accessing our Realtime database is very similar to accessing the storage. Lines 96 and 92 are very similar except we change what were trying to access. When we have our reference to the database, we .push() and pass in an object with key value pairs as demonstrated on lines 97–100 in the code snippet above.

This is where we set our state using the database with a Firebase event listener.

In this componentDidMount()theres a special Cloud Function, .on(). Here, we again reference our database on line 22. .on() essentially waits for changes on a particular document, it triggers when an event occurs, and receives an object containing two snapshots of data stored in that particular reference. Data prior to the change and the new data. In our case we basically want to set the state of the component when a “child is added” or when the user uploads that mp3 file. Then we can set the source of our audio tag to that download URL.

let song = this.state.song;
<audio src={song} ref={this.audioDidMount} loop />

All thats left is that realtime listening with your friends!

This is where most of the magic happens. First, we set a reference in our database called “paused”. If you’re wondering why “paused” instead of “play”, it’s because the audio tag has a pause() method and for the sake of our sanity, the logic to name it pause just made more sense. Once we have the reference to pause, we can change the value of that reference to either true or false as shown on line 53 with set() which saves data to our specified reference, overwriting what we had. If paused === true, pause the audio. Otherwise, play the audio. Once the user clicks on the play button, handlePlayPauseClick() is invoked and does this wonderful, cool, realtime listening thing that toggles the “pause” reference to true or false. Thats essentially it!

Making this web application was definitely challenging since it was Noelle and I’s first time working with Firebase but nonetheless it was incredibly fun and rewarding to see this creation come to life. All thanks to this incredible technology, Firebase. Stick around for some other cool posts on how I get things to work. 🔥 🔥 🔥

--

--

Luis Miguel Rincon

Former Flight Attendant, now living in New York City as a full stack developer