The site is under maintenance.

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 ? &quot;1&quot; : &quot;false&quot;' expr:data-path='&quot;/BLOG_&quot; + data:blog.blogId + &quot;/POST_&quot; + data:post.id + &quot;/VIEWS&quot;'/>

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 &lt;/body&gt;.

<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>

About the Author

Hey! I'm Deo Kumar, a passionate web developer skilled in JavaScript, Node.js, Cloudflare Workers, KV stores, and Next.js. With a focus on dynamic web applications, I excel in JavaScript and Node.js, ensuring robust websites. As a front-end expe…

3 comments

  1. 👏👏👏🔥
  2. how to implement in plus UI how
    1. Plus UI has inbuilt view counter. No need to add these scripts.
To avoid SPAM, all comments will be moderated before being displayed.
Don't share any personal or sensitive information.
Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.