
EdTech Platform Types ExplainedRead More

Real-time communication enhances user experience (UX), and real-time updates on what has happened. You would not want to reload to check if you have received a message right? Or check if you have received any notifications. Following are just a few basic examples of real-time communication:
Some complex applications for real-time:
Web socket is a persistent, full-duplex communication channel between the client and server. Unlike HTTP, which is request-driven, WebSockets maintain a continuous connection, enabling real-time data exchange.
native WebSockets offer direct control, vs libraries like Socket.IO, SockJs offers the following:
Firebase, Google’s Backend-as-a-Service (BaaS) platform, offers a Realtime Database and Cloud Firestore, both of which support live synchronization of data across devices.
Real-time collaboration tools enable multiple users to work on the same document simultaneously. Let's move step-by-step to implement a collaborative document editor using Firebase for data persistence and WebSockets for real-time communication.
Create a New Project Directory
mkdir collaborative-editor
cd collaborative-editorInitialize a Node.js Project
npm init -yInstall Firebase SDK Inside the project directory:
npm install firebase
npm install -g http-serverSet Up the Directory Structure
mkdir clientCreate a Firebase Project
Initialize Firebase in Your Project
// client/firebaseConfig.js
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.2/firebase-app.js";
import { getDatabase } from "https://www.gstatic.com/firebasejs/9.22.2/firebase-database.js";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
databaseURL: "https://YOUR_PROJECT_ID.firebaseio.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT_ID.appspot.com",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID"
};
const app = initializeApp(firebaseConfig);
export const db = getDatabase(app);
Create an HTML File Inside the client directory:
<!-- client/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Collaborative Editor</title>
</head>
<body>
<textarea id="editor" style="width: 100%; height: 80vh;"></textarea>
<script src="./index.js" type="module"></script>
</body>
</html>
Implement Real-Time Synchronization:
// client/index.js
import { db } from "./firebaseConfig.js";
import {
ref,
onValue,
set,
} from "https://www.gstatic.com/firebasejs/9.22.2/firebase-database.js";
const docRef = ref(db, "documents/doc1");
const textArea = document.getElementById("editor");
// Listen for Firebase updates
onValue(docRef, (snapshot) => {
const data = snapshot.val();
if (data && textArea.value !== data.text) {
textArea.value = data.text;
}
});
// Save text to Firebase
textArea.addEventListener('input', () => {
const text = textArea.value;
set(docRef, { text });
});
To run the implementation
cd client
http-server
You should be able to do the following at this point.
Let's enhance the UI a little bit and add interesting features.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Collaborative Editor</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f4f4f9;
}
header {
background-color: #6200ea;
color: white;
padding: 1rem;
text-align: center;
}
textarea {
width: 100%;
height: calc(80vh - 2rem);
border: none;
resize: none;
padding: 1rem;
font-size: 1rem;
background: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
outline: none;
margin: 1rem auto;
}
footer {
text-align: center;
padding: 1rem;
font-size: 0.9rem;
background-color: #6200ea;
color: white;
}
button {
margin: 0.5rem;
padding: 0.5rem 1rem;
background: #6200ea;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background: #3700b3;
}
</style>
</head>
<body>
<header>
<h1>Collaborative Editor</h1>
</header>
<textarea id="editor" placeholder="Start typing..."></textarea>
<footer>
<button id="clearButton">Clear</button>
<button id="exportButton">Export</button>
</footer>
<script src="./index.js" type="module"></script>
</body>
</html>
Clear Text and Export Text
// Clear text for all users
document.getElementById("clearButton").addEventListener("click", () => {
if (confirm("Are you sure you want to clear the document?")) {
set(docRef, { text: "" });
}
});
// Export text to a .txt file
document.getElementById("exportButton").addEventListener("click", () => {
const text = textArea.value;
const blob = new Blob([text], { type: "text/plain" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "document.txt";
link.click();
});
Update firebaseConfig.js (new presence logic):
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.2/firebase-app.js";
import { getDatabase, ref, onDisconnect, set } from "https://www.gstatic.com/firebasejs/9.22.2/firebase-database.js";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
databaseURL: "https://YOUR_PROJECT_ID.firebaseio.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT_ID.appspot.com",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID",
};
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);
// User presence tracking
const userRef = ref(db, "users/" + Math.random().toString(36).substring(2));
set(userRef, true);
onDisconnect(userRef).remove();
export { db };
Update index.js:
// Updated imports
import { db } from "./firebaseConfig.js";
import {
ref,
onValue,
set,
onDisconnect,
get,
child,
} from "https://www.gstatic.com/firebasejs/9.22.2/firebase-database.js";
// User presence logic
const usersRef = ref(db, "users");
onValue(usersRef, (snapshot) => {
const users = snapshot.val() ? Object.keys(snapshot.val()).length : 0;
document.querySelector("header").innerHTML = `<h1>Collaborative Editor - ${users} Users Online</h1>`;
});
New database structure:
{
"documents": {
"doc1": {
"text": "Current content",
"history": {
"timestamp1": "Previous content",
"timestamp2": "Another previous content"
}
}
}
}
Update index.js:
// Save version history
textArea.addEventListener("input", () => {
const text = textArea.value;
const timestamp = Date.now();
set(docRef, { text });
set(ref(db, `documents/doc1/history/${timestamp}`), text);
});
// Revert to previous version
function revertToVersion(timestamp) {
get(child(docRef, `history/${timestamp}`)).then((snapshot) => {
if (snapshot.exists()) {
set(docRef, { text: snapshot.val() });
}
});
}
Finally, here is how your implementation should look and work:
Conflict Resolution
Offline Mode
Security
{
"rules": {
"documents": {
"$docId": {
".read": "auth != null",
".write": "auth != null"
}
}
}
}
Performance Optimization
Testing
Adding real-time features with WebSockets and Firebase makes web apps more interactive. Following best practices ensures they are secure and efficient. As users expect instant updates, using these tools can help create smooth and engaging experiences. Real-time tech is becoming a must-have for modern web apps. Investing in it now will keep your app fast, responsive, and ready for the future.
Trusted by top platforms for our transformative solutions and exceptional results:






