How to Say Goodbye to Manual Refresh and Enjoy Instant Updates via Firebase onSnapshot listener?
Unveiling the Wonders of Real-Time Data Updates Through Firebase onQuerysnapshot.
Imagine🤔 you’re on an app/website providing quality insights or information. Whenever you need the latest info, you keep tapping on the “Refresh” button or swiping down or reloading the page.
It’s like casting a spell 🪄to get new data. We’ve all been there — the boring cycle of refreshing, waiting, and hoping for a change that never seems to come.
Manual refresh is a part of traditional data refreshing methods and is been for a long time. It comes with certain disadvantages that can impact user experience and overall application efficiency.
Problem with Manual User-Triggered Refresh
With this method, users manually initiate data refresh by interacting with a “Refresh” button or gesture. While it provides more control, it demands user effort and lacks the seamless real-time experience users now expect.
Anytime you feel like In a world where information flows at the speed of thought,
Why are we still grappling with the ancient ritual of a manual refresh?
Isn’t there a better way to keep our applications up-to-date with the latest data?
But what If I tell you there’s a better way? where the application gracefully dances🕺 with the rhythm of incoming information, and automatically refreshes🔄 itself whenever there’s something new to share.
No more tapping, no more waiting…
But why real-time data refresh is required?
Instant Updates — In today’s fast-paced world, users expect to see changes as soon as they occur. Real-time refresh ensures that users receive updates immediately after they are made, creating a seamless and dynamic user experience.
Current Information — Real-time refresh prevents users from encountering outdated or stale data. It ensures that the displayed information is always current, accurate, and relevant.
Reduced User Effort — Real-time refresh eliminates the need for users to manually refresh the application to see the latest updates. This convenience enhances user satisfaction and reduces frustration.
Real-world examples
Ride-sharing apps like Uber and Rapido utilize real-time updates to provide users with precise information about nearby drivers’ locations and estimated arrival times.
This enables passengers to track their rides in real time and ensures a seamless and transparent experience from booking to drop-off. Real-time location updates also play a crucial role in driver navigation, allowing them to reach passengers efficiently and reduce wait times.
With that Introducing
Firebase Cloud Firestore onQuerySnapshot Listener
Google’s comprehensive application development platform, offers a solution that replaces the limitations of traditional data refresh methods.
Cloud Firestore, is a NoSQL cloud database designed for building web, mobile, and server applications.
It works in near real-time, automatically fetching changes to the database as they happen through real-time listeners.
The onQuerySnapshot listener is a crucial component of Firebase’s Cloud Firestore database.
How does it work?
The listener listen for changes to a query's result set and receive real-time updates whenever there are changes to the data that match the query.
Advantages of Firebase’s onQuerySnapshot
Listener over manual refresh
- Real-Time Updates — Unlike periodic polling, the
onQuerySnapshot
listener triggers updates in real time whenever changes occur in the data, ensuring users see changes as they happen. - Efficiency — By avoiding continuous polling, the listener reduces unnecessary network requests and minimizes the impact on server resources, resulting in a more efficient application.
- Reduced Latency — Updates are delivered quickly, reducing the delay between changes happening on the server and those changes being visible to users.
- Simplicity — The listener abstracts the complexities of data update handling, making implementation straightforward and easing the burden on developers.
Cloud Firestore is also available in native Node.js, Java, Python, Unity, C++ and Go SDKs, in addition to REST and RPC APIs.
Now let's see how can we implement the Realtime data refresh with a simple voting application.
Create a React app using
npx create-react-app myvote-demo
Setting up the project in Firebase
Just like before we start our journey to a place we pack our bags. In the same way, we need to set up the project and get some keys from the Firebase project to start with.
set up the Firebase project and get the necessary keys by Following the Firebase official documentation -> click here
After setting up your project and registering your app,
Install the Firebase SDK using the command (make sure you have node.js installed on your machine)
npm install firebase
Initialize Firebase inside app.js (Replace FIREBASE_CONFIGURATION
with your configuration keys)
// Import the functions you need from the SDKs you need
import logo from './logo.svg';
import './App.css';
import { initializeApp } from "firebase/app";
function App() {
// TODO: Replace the following with your app's Firebase project configuration
const firebaseConfig = {
FIREBASE_CONFIGURATION
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
return (
<div className="App">
Hello world!
</div>
);
}
export default App;
Firebase services (like Cloud Firestore, Authentication, Realtime Database, Remote Config, and more) are available to import within individual sub-packages.
import Firstore into app.js and initialize the Firestore. Now app.js looks like
import logo from './logo.svg';
import './App.css';
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
function App() {
// TODO: Replace the following with your app's Firebase project configuration
const firebaseConfig = {
FIREBASE_CONFIGURATION
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore(app);
return (
<div className="App">
Hello world!
</div>
);
}
export default App;
Go to your Firebase console-> Build-> Firestore-> click Create Database
Create a collection using “start collection” with the following specifications
collection name: Options
document ID: Auto-generate
fields:
1. name(string) — no default
2. voteCount(number) — default value=0
based on the collection adding the code to get the real-time updates using onsnapshot inside app.js
//add these imports at start
import { useState,useEffect } from 'react';
//adding additional import to the firebase/firestore import
import { doc,
getFirestore,
increment,
collection,
onSnapshot,
query,
updateDoc }
from "firebase/firestore";
const [options, setOptions] = useState([]);
useEffect(() => {
// Set up the onQuerySnapshot listener on a collection
// for more info https://firebase.google.com/docs/firestore/query-data/listen#listen_to_multiple_documents_in_a_collection
const unsubscribe = onSnapshot(query(collection(db, "options")), (snapshot) => {
const updatedOptions = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setOptions(updatedOptions);
});
// Cleanup listener
return () => unsubscribe();
}, []);
const handleVote = (optionId) => {
updateDoc(doc(db, "options", optionId), {
voteCount: increment(1)
})
};
adding an un-ordered list inside the <div className="App"></div>
to show the votes
<h1>Real-Time Voting App</h1>
<ul>
{options.map((option) => (
<li key={option.id}>
{option.name} - Votes: {option.voteCount}
<button onClick={() => handleVote(option.id)}>Vote</button>
</li>
))}
</ul>
after adding this your app.js looks like this...
import logo from './logo.svg';
import './App.css';
import { initializeApp } from "firebase/app";
import { useState,useEffect } from 'react';
//adding additional import to the firebase/firestore import
import { doc,
getFirestore,
increment,
collection,
onSnapshot,
query,
updateDoc }
from "firebase/firestore";
function App() {
// TODO: Replace the following with your app's Firebase project configuration
const firebaseConfig = {
FIREBASE_CONFIGURATION
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore(app);
const [options, setOptions] = useState([]);
useEffect(() => {
// Set up the onQuerySnapshot listener on a collection
// for more info https://firebase.google.com/docs/firestore/query-data/listen#listen_to_multiple_documents_in_a_collection
const unsubscribe = onSnapshot(query(collection(db, "options")), (snapshot) => {
const updatedOptions = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setOptions(updatedOptions);
});
// Cleanup listener
return () => unsubscribe();
}, []);
const handleVote = (optionId) => {
updateDoc(doc(db, "options", optionId), {
voteCount: increment(1)
})
};
return (
<div className="App">
<h1>Real-Time Voting App</h1>
<ul>
{options.map((option) => (
<li key={option.id}>
{option.name} - Votes: {option.voteCount}
<button onClick={() => handleVote(option.id)}>Vote</button>
</li>
))}
</ul>
</div>
);
}
export default App;
Run the app using npm start
I Duplicated the tab which runs on localhost:3000
to show the real-time update on the second tab.
You can see that if I click any button on the left side tab the value gets updated on both the left side and right side tabs.
That's the power of onSnapshot
It's not the end or only example of onSnapshot, there can be many such applications beyond the demonstrated voting app example.
you can head on to Firebase cloud Firestore Read-data for more info on Realtime data updates for Firestore.
Hurray you have made it to the end of the tutorial. Hope you liked it.
I appreciate your feedback on this article. Your thoughts and suggestions help me improve my content. Thank you! 😊👍
Happy Designing & Developing.