— gatsby, firebase — 1 min read
Tutorial on integrating firebase on client side, particularly Firestore.
I hope to follow up with
This post is not a complete solution on firestore backed commenting system.
Following steps are required to get this working
1yarn add firebase
Add comment.tsx
react component that fetches data from firestore.
For react component to interact with firestore we need to initialize firebase and setup firestore
configuration.
1const app = initializeApp(firebaseConfig);2const db = getFirestore(app);
For local development instead of talking to production firestore we run local emulator. which is accessible at 8080
1if (process.env.NODE_ENV === "development") {2 connectFirestoreEmulator(db, "localhost", 8080);3}
Using firebase emulator makes development process faster in a long run. To use firebase emulator make sure that you have firebase cli installed.
1firebase emulators:start
Once done open http://localhost:4000/ add collection blogPosts
Update comments.tsx to fetch data from firestore
1const commentsCol = query(2 collection(db, "blogPosts"),3 where("slug", "==", slug)4);5const commentSnapshot = await getDocs(commentsCol);6const commentList = commentSnapshot.docs.map((doc) => doc.data()) as Comment[];
Once you have comments from firestore we set it in state and render it.
1setComments(commentList);
To render it
1<ul>2 {comments.map((comment) => (3 <li key={comment.comment}>{comment.comment}</li>4 ))}5</ul>
The entire change set would be something like below
1diff --git a/package.json b/package.json2index 29f4857..6b19348 1006443--- a/package.json4+++ b/package.json5@@ -17,6 +17,7 @@6 },7 "dependencies": {8 "@lekoarts/gatsby-theme-minimal-blog": "^2.2.2",9+ "firebase": "^9.6.1",10 "gatsby": "^2.13.3",11 "gatsby-plugin-disqus": "^1.2.3",12 "gatsby-plugin-google-analytics": "^2.1.4",13diff --git a/src/@lekoarts/gatsby-theme-minimal-blog/components/comments.tsx b/src/@lekoarts/gatsby-theme-minimal-blog/components/comments.tsx14index e69de29..0b775f9 10064415--- a/src/@lekoarts/gatsby-theme-minimal-blog/components/comments.tsx16+++ b/src/@lekoarts/gatsby-theme-minimal-blog/components/comments.tsx17@@ -0,0 +1,66 @@18+import React from "react";19+20+import { initializeApp } from "firebase/app";21+import {22+ collection,23+ connectFirestoreEmulator,24+ getDocs,25+ getFirestore,26+ query,27+ where,28+} from "firebase/firestore/lite";29+30+import { useEffect } from "react";31+import { useState } from "react";32+const firebaseConfig = {33+ projectId: "chandankumar-com",34+};35+36+type CommentProp = {37+ slug: string;38+};39+40+type Comment = {41+ slug: string;42+ comment: string;43+};44+45+const Comment = (prop: CommentProp) => {46+ const { slug } = prop;47+ const [comments, setComments] = useState<Comment[]>(null);48+49+ async function getComments() {50+ const app = initializeApp(firebaseConfig);51+ const db = getFirestore(app);52+ if (process.env.NODE_ENV === "development") {53+ connectFirestoreEmulator(db, "localhost", 8080);54+ }55+ const commentsCol = query(56+ collection(db, "blogPosts"),57+ where("slug", "==", slug)58+ );59+ const commentSnapshot = await getDocs(commentsCol);60+ const commentList = commentSnapshot.docs.map((doc) =>61+ doc.data()62+ ) as Comment[];63+ setComments(commentList);64+ }65+66+ useEffect(() => {67+ getComments();68+ }, []);69+ return (70+ <div>71+ <h3>Comments</h3>72+ {comments && (73+ <ul>74+ {comments.map((comment) => (75+ <li key={comment.comment}>{comment.comment}</li>76+ ))}77+ </ul>78+ )}79+ </div>80+ );81+};82+83+export default Comment;84diff --git a/src/@lekoarts/gatsby-theme-minimal-blog/components/post.tsx b/src/@lekoarts/gatsby-theme-minimal-blog/components/post.tsx85index b4efeee..7bc706e 10075586--- a/src/@lekoarts/gatsby-theme-minimal-blog/components/post.tsx87+++ b/src/@lekoarts/gatsby-theme-minimal-blog/components/post.tsx88@@ -5,7 +5,7 @@ import React from "react";89 import Layout from "@lekoarts/gatsby-theme-minimal-blog/src/components/layout";90 import ItemTags from "@lekoarts/gatsby-theme-minimal-blog/src/components/item-tags";91 import SEO from "@lekoarts/gatsby-theme-minimal-blog/src/components/seo";92+import Comment from "./comments";9394 type PostProps = {95 data: {96@@ -71,6 +71,7 @@ const Post = ({ data: { post } }: PostProps) => (97 }}98 >99 <MDXRenderer>{post.body}</MDXRenderer>100+ <Comment slug={post.slug} />101 </section>102 {/* <Disqus config={{ identifier: post.slug, title: post.title }} /> */}103 </Layout>