Get page views from Firebase Analytics in a Gatsby site
Hello, I’m currently using Firebase Analytics on my blog and would like to display page views for each individual post. While researching online today, I found that the information I encountered was outdated. With Google transitioning from Universal Analytics to GA4, I’m looking for a new approach to achieve my goal.
Here’s a step-by-step guide on how to set up Firebase Analytics to log page views and how you can retrieve this data using the Google Analytics Data API Client:
Step 1: Set Up Firebase Analytics to Log Page Views
Follow instruction in Setting up Firebase Analytics in a GatsbyJS application to initialize Firebase Analytics in your site
Next, now you need to log page view each time user visit your post page
Add the following lines to your blog post page:
React.useEffect(() => {
if (typeof window !== "undefined" && firebase.analytics) {
firebase
.analytics()
.logEvent("page_view", { page_path: data.mdx.fields.slug });
}
}, []);
Sample from my blog
import * as React from "react";
import { HeadFC, graphql } from "gatsby";
import firebase from "gatsby-plugin-firebase";
const BlogPost = ({ data, children }: any) => {
React.useEffect(() => {
if (typeof window !== "undefined" && firebase.analytics) {
firebase
.analytics()
.logEvent("page_view", { page_path: data.mdx.fields.slug });
}
}, []);
return (
<main>
<div className="mx-auto max-w-screen-xl flex flex-col">
<div className="p-4">
<h1 className="text-2xl font-bold mb-4 mt-4">
{data.mdx.frontmatter.title}
</h1>
<div className="mt-4 [&>p]:mb-4 [&>pre]:mb-4 post">{children}</div>
</div>
</div>
<Footer />
</main>
);
};
export const query = graphql`
query ($id: String) {
mdx(id: { eq: $id }) {
id
frontmatter {
title
subtitle
date(formatString: "MMMM D, YYYY")
}
fields {
slug
}
}
}
`;
export default BlogPost;
Step 2: Retrieve Analytics Data Using Google Analytics Data API Client
The process is similar to the Universal Analytics Reporting API but with some differences in the API endpoints and request structure.
1. Install Google Analytics Data API Client and Crypto:
npm install @google-analytics/data crypto
2. Create a Service Account:
Go to the Firebase Console.
Choose your project
Navigate to Project Settings and then to Service Accounts.
Create a new service account and download the JSON key file.
3. Enable Google Analytics Data API
Head over to Google Console and enable Google Analytics Data API service
4. Fetch Analytics Data in gatsby-node.js:
Use the @google-analytics/data package to fetch analytics data in your gatsby-node.js file.
Example code in gatsby-node.js:
const crypto = require("crypto");
const { BetaAnalyticsDataClient } = require("@google-analytics/data");
const analyticsDataClient = new BetaAnalyticsDataClient({
credentials: {
client_email: YOUR_CLIENT_EMAIL,
private_key: YOUR_PRIVATE_KEY,
},
});
exports.sourceNodes = async ({ actions }) => {
const { createNode } = actions;
const [response] = await analyticsDataClient.runReport({
property: "properties/YOUR_PROPERTY_ID",
dateRanges: [
{
startDate: "30daysAgo",
endDate: "today",
},
],
dimensions: [
{
name: "pagePath",
},
],
metrics: [
{
name: "screenPageViews",
},
],
orderBys: [
{
desc: true,
metric: {
metricName: "screenPageViews",
},
},
],
});
// Process the response data.
let rows = response.rows;
rows = rows.map((row) => {
const path = row.dimensionValues[0].value;
const totalCount = row.metricValues[0].value;
return {
path,
totalCount,
};
});
// Add analytics data to graphql
for (const { path, totalCount } of rows) {
createNode({
path,
totalCount: Number(totalCount),
id: path,
internal: {
type: `PageViews`,
contentDigest: crypto
.createHash(`md5`)
.update(JSON.stringify({ path, totalCount }))
.digest(`hex`),
mediaType: `text/plain`,
description: `Page views per path`,
},
});
}
};
YOUR_CLIENT_EMAIL and YOUR_PRIVATE_KEY you can read from service account JSON key file
5. How can you get YOUR_PROPERTY_ID?
Go to the Google Analytics dashboard.
Select the desired account and property
Click on the Admin gear icon located in the bottom left corner.
Navigate to Property Settings, then to Property, and finally Property Details.
You will find YOUR_PROPERTY_ID in the top right corner.
6. Next, Ensure the Service Account Has Access
Click on Property access management
Add the service account email (found in your service account JSON key file under client_email) with Viewer or Editor permissions.
7. Run a test
Note that contentDigest should be unique because it is used for caching
Now run npm start and check localhost:8000__graphql there should be two new fields to query, pageViews and allPageViews. The first takes an id (slug) as parameter, the second displays all pages.
Example allPageViews query
Step 3: Displaying the new data
Now that we can get our page views from graphql
import * as React from "react";
import { HeadFC, graphql } from "gatsby";
import firebase from "gatsby-plugin-firebase";
const BlogPost = ({ data, children }: any) => {
React.useEffect(() => {
if (typeof window !== "undefined" && firebase.analytics) {
firebase
.analytics()
.logEvent("page_view", { page_path: data.mdx.fields.slug });
}
}, []);
const pageView = data.allPageViews.nodes.find(
(p: any) => p.path === data.mdx.fields.slug
);
return (
<main>
<div className="mx-auto max-w-screen-xl flex flex-col">
<div className="p-4">
<h1 className="text-2xl font-bold mb-4 mt-4">
{data.mdx.frontmatter.title}
</h1>
<div className="flex text-sm gap-3 items-center text-gray-500">
<span>{pageView?.totalCount ?? 0} VIEWS</span>
</div>
<div className="mt-4 [&>p]:mb-4 [&>pre]:mb-4 post">{children}</div>
</div>
</div>
</main>
);
};
export const query = graphql`
query ($id: String) {
mdx(id: { eq: $id }) {
id
frontmatter {
title
subtitle
date(formatString: "MMMM D, YYYY")
}
fields {
slug
}
}
allPageViews {
nodes {
path
totalCount
}
}
}
`;
export default BlogPost;
That's it