Realtime View Counter using Firebase Database
After a long time, I am back with an article titled "Realtime View Counter using Firebase Database". Today, I am going to share a Firebase Realtime Database Project that counts Post Views or any event. This is my first project I have tried with Typescript and Firebase v9.
As it uses Firebase Javascript SDK, the size of the bundle is a little bit large. I tried using the Firebase Database REST API but the response was quite slower than SDK, so I had to use the Javascript SDK for a better performance.
Using it as View Counter
You can use it as a View Counter for your post just by specifying the path. Let's try adding it to a Blogger Website.
Important!Before we start adding codes in XML, I will recommend you to take a Backup of your current theme. By chance if any problem occurs, you can restore it later.
Step 1: First of all Login to your Blogger Dashboard.
Step 2: On Blogger Dashboard, click Theme.
Step 3: Click the arrow down icon next to 'customize' button.
Step 4: Click Edit HTML, you will be redirected to editing page.
Step 5: Now search the code ]]></b:skin>
and paste the following CSS Codes just above to it.
If your template has a dark mode feature, and if you want a different color when in dark mode, you can customise the codes as per your need. Each template can have a different dark mode class, so please adjust it, you can replace the marked class with your template dark mode class.
[data-path] {
--text-color: #000;
--text-color-dark: #fff;
--icon-loading: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50' x='0px' y='0px' fill='%23000'><path d='M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z'><animateTransform attributeName='transform' attributeType='xml' dur='0.6s' from='0 25 25' repeatCount='indefinite' to='360 25 25' type='rotate'></animateTransform></path></svg>");
--icon-eye: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.25'><path d='M15.58 12c0 1.98-1.6 3.58-3.58 3.58S8.42 13.98 8.42 12s1.6-3.58 3.58-3.58 3.58 1.6 3.58 3.58Z'></path><path d='M12 20.27c3.53 0 6.82-2.08 9.11-5.68.9-1.41.9-3.78 0-5.19-2.29-3.6-5.58-5.68-9.11-5.68-3.53 0-6.82 2.08-9.11 5.68-.9 1.41-.9 3.78 0 5.19 2.29 3.6 5.58 5.68 9.11 5.68Z'></path></svg>");
--text-loading: "--- --";
--text-loaded: attr(data-view);
--border-color: rgba(0, 0, 0, 0.1);
--border-color-dark: rgba(255, 255, 255, 0.2);
line-height: 1rem;
padding: 10px;
border: 1px solid var(--border-color);
border-radius: 5px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
font-size: 14px;
color: var(--text-color);
}
[data-path]::before {
content: "";
width: 20px;
height: 20px;
background-size: 20px;
background-repeat: no-repeat;
background-position: center;
opacity: 0.8;
-webkit-mask: var(--svg-icon);
mask: var(--svg-icon);
background: var(--text-color);
--svg-icon: var(--icon-loading);
}
[data-path][data-view]::before {
--svg-icon: var(--icon-eye);
}
[data-path]::after {
content: var(--text-loading);
opacity: 0.8;
}
[data-path][data-view]::after {
content: var(--text-loaded);
}
.drK [data-path] {
--text-color: var(--text-color-dark);
--border-color: var(--border-color-dark);
}
Step 6: This step is a little bit tricky as you have to find where do you want to add the view counter in your template. You have to find the correct place as per your template and paste it there, for example: above <data:post.body/>
<div class='post-view' expr:data-increment='data:view.isPost ? "1" : "false"' expr:data-path='"/BLOG_" + data:blog.blogId + "/POST_" + data:post.id + "/VIEWS"'/>
Step 7: Now add the following Javascript just above to </body>
tag. If you don't find it, it is probably already parsed which is </body>
.
<script>
function viewCounterLoaded () {
const counter = new ViewCounter({
databaseUrl: "https://example.firebaseio.com",
selector: ".post-view",
abbreviation: true
});
if (typeof infinite_scroll !== "undefined") {
infinite_scroll.on("load", counter.init.bind(counter));
}
};
</script>
<script defer onload='viewCounterLoaded()' src='https://cdn.jsdelivr.net/gh/fineshopdesign/view-counter@main/build/bundle.js'></script>
Step 7: Lastly, Save the changes by clicking on this icon
Using it as Click Counter
<style>
.click-counter::before {
content: "0"
}
.click-counter[data-view]::before {
content: attr(data-view);
}
</style>
<button class='click-button'>Clicks (<span class='click-counter' data-path='/BLOG_0000/POST_0001/CLICKS' data-increment='false'></span>)</button>
<script>
function viewCounterLoaded () {
const counter = new ViewCounter({
databaseUrl: "https://example.firebaseio.com",
abbreviation: true
});
const clickButton = document.querySelector(".click-button");
const clickCounter = document.querySelector(".click-counter");
counter.addElement(clickCounter).then(function(counterElement) {
clickButton.addEventListener("click", function() {
counterElement.increment(1);
});
});
};
</script>
<script defer="" onload="viewCounterLoaded()" src="https://cdn.jsdelivr.net/gh/fineshopdesign/view-counter@main/build/bundle.js"></script>