Real-time Code Sharing Application Using React and Firebase Part-3

Saad Hassan
5 min readNov 24, 2018

Wiring the app with Firebase Real-time Database

Previous Post: Part-2: Implementing React Router for Navigation and Code Mirror Editor

Firebase Configuration

Go to the the Project dashboard you created in firebase console and copy the configuration of the Realtime Database for web. Below is the sample of configuration file.

var config = {
apiKey: "------------------------",
authDomain: "sh-codesharerealtime.firebaseapp.com",
databaseURL: "https://sh-codesharerealtime.firebaseio.com",
projectId: "sh-codesharerealtime",
storageBucket: "sh-codesharerealtime.appspot.com",
messagingSenderId: "---------------"
};

Now lets install firebase package that we will need for using various firebase services.

npm i -S firebase

Now Lets create a config json file in our src and copy configurations. Second step is to initialize firebase app with the configuration. So lets edit index.js accordingly.

import * as firebase from "firebase";
import * as config from "./firebase-config.json"; // Config Json File we created
firebase.initializeApp(config);

Once the app has been initialized the firebase instance you import will be configured automatically with this configuration.

What database structure we need?

Its simple flat data structure, we need the content of editor and timestamp it was created along with a unique identification session key which will help other users to navigate to the same play ground.

Sample of the data structure is :

"code-sessions": {
"Qee13": {
"content": "// Code",
"createdon": "09-11-2017 06:00 PM"
},
.....
}

Creating New Session

On the homepage we will create a button which on Click action will create new session and navigate user to that coding ground.

// containers/pages/Home.jsimport { database } from "firebase";
import rand from "random-key";
state = {
key: rand.generate(5),
};

We will import database instance from firebase and then generate and store random 5 digit key in the internal state which will act as a reference in our database for the session identification.

<button className="btn" onClick={this.onNewGround}>Share Code
</button>
onNewGround = () => {
database()
.ref("code-sessions/" + this.state.key)
.set({
content: "Happy Coding",
createdon: Date()
});
this.props.history.push("/" + this.state.key);
};

Now lets create the button and on Click action we will create new entry in our Firebase Realtime Database. Lets set default content to Happy Coding and createdon to Date().

React Router <Routes > passes down the history prop which helps in pushing new route that will navigate user to that url.

So once the database entry is created we will naviagte user to that url. Now its the job of Coding page to take the session id from param and get the data from database.

Wiring Editor with the content in Database

// containers/pages/Home.jsimport { database } from "firebase";state = {
code: "Loading...",
cursorPosition: {
line: 0,
ch: 0
}
};

We import the database and set the default state code to Loading... and cursor postions to line: 0, ch: 0.

componentDidMount = () => {
const { params } = this.props.match;
let self = this;
database()
.ref("/code-sessions/" + params.sessionid)
.once("value")
.then(snapshot => {
self.setState({ code: snapshot.val().content + "", createdon: snapshot.val().createdon }, () => {
let content = snapshot.val().content;
self.codemirror.getCodeMirror().setValue(content);
});
// We will update code on new value event later here.. })
.catch(e => {
self.codemirror.getCodeMirror().setValue("No Sessions Found!");
});
};

Since CodeMirror Wrapper we are using doesn’t provide the methods to set content of the editor we will be requiring the instance of CodeMirrorEditor which we can get once componentDidMount. So taking that reference we will update the state and editors code with snapshots content.

firebase database instance provides a method to get reference data once. So we will use that method to get data once the component did mount and update the editor.

We will be needing a event that updates database once the code is changed that gets reflected to all the users using same session. For this we will use codeRef.on('value') event which will trigger everytime the sessions content is updated in the database. We will implement changeCursorPos method and add update editor code below the comment we used earlier.

changeCursorPos = () => {
const { line, ch } = this.state.cursorPosition;
this.codemirror.getCodeMirror().doc.setCursor(line, ch);
};
componentDidMount = () => {
...
// We will update code on new value event later here..
this.codeRef = database().ref("code-sessions/" + params.sessionid);
this.codeRef.on("value", function(snapshot) {
self.setState({
code: snapshot.val().content
});
var currentCursorPos = self.state.cursorPosition;
self.codemirror.getCodeMirror().setValue(snapshot.val().content);
self.setState({ cursorPosition: currentCursorPos });
self.changeCursorPos();
});
})
...
};

Now we need to set data to the databse to once user changes the editor code too. So we will implement onChange method and hook that with <CodeMirror> Component

onChange = (newVal, change) => {
this.setState(
{
cursorPosition: {
line: this.codemirror.getCodeMirror().doc.getCursor().line,
ch: this.codemirror.getCodeMirror().doc.getCursor().ch
}
}
);
this.codeRef.child("content").set(newVal);
};
<CodeMirror
...
onChange={this.onChange} />

Note: You might have saw the cursor position i am tracking. This is needed so that on update the users cursor remain placed to the same position he was already when other user updated the content from other session.

Once this is done you are set to go you can share the url and test for Realtime changes. It would reflect immediately. Thats it, Firebase Realtime database works perfectly for our app.

Deploy the App

Now you set to share your app to the world. Build the App with the command

npm run build

Configure firebase.json to rewrite all your routes to build/index.html

{
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

And then deploy the changes.

firebase deploy

You will get hosting url similar to your projectname.firebaseapp.com. For example mine is

https://sh-codesharerealtime.firebaseapp.com/

Checkout the app. And Thanks for sticking for so long.

Congrats 🎉🎊. We are done with Realtime Cod Sharing App. You can enhance app adding various features to editor as well as authentication to the app using Firebase.

  1. Part-1: Creating Simple React App and Deploying it on Firebase
  2. Part-2: Implementing React Router for Navigation and Code Mirror Editor
  3. Part-3: Wiring the app with Firebase Real-time Database

This post was first published on my blog.

--

--