通过firebase搭建一个评论系统, part 1
2020年11月17日 • ... • ☕️ 4 min read
随着评论习惯慢慢改变,之前如火如荼的博客慢慢消沉下去了,随之慢慢冷淡下去的是博客连接起来的评论圈子,例如在各个博客下面留言“混个脸熟”,还有通过评论来推广链接等做法,也慢慢淡出我们的视线。
于是,很多博客,尤其是静态博客,要么直接内嵌基于github的comments,第三方disqus或者是直接没有评论。评论虽然不是必需品,但是作为一个blog,一个适当的评论模块当然是锦上添花。
之前使用了disqus,但是载入一堆js,而且样式还只能魔改,对于有些强迫症的朋友不太友好。所以自建一套评论系统便一直萦绕在脑袋里。
首先是数据保存,办法一般是在github上存储,或者使用数据库。如果不想架vps,那就要使用第三方数据库服务了。
具体步骤,我是参考的这篇 How To Build Your Own Comment System Using Firebase。
实现步骤
确定唯一标识
使用过disqus的知道,它的config需要几个字段:identifier、url、title
,其中identifier是文章的唯一标识,既然通过这个唯一标识能建立数据库到文章的连接,那么自己建立一个数据库,然后打开文章的时候,单独操作相关数据就可以了。
这个标识可以是文章id,或者设置的链接名(通常是英文)。
申请并配置firebase
这个推荐参考官方文档,或上面提供的链接。根据实际需要,可以考虑使用实时数据库或者firestore。
代码部分
firebase提供了npm包,这个sdk可以直接引入项目中使用。基本步骤是通过config初始化firebase,利用api来读写数据。
初始化:
import firebase from 'firebase/app';
import 'firebase/database';
const firebaseConfig = {
apiKey: 'key',
appId: 'key',
authDomain: 'key',
databaseURL: 'key',
measurementId: 'key',
messagingSenderId: 'key',
projectId: 'key',
storageBucket: 'key',
};
firebase.initializeApp(firebaseConfig);
const db = firebase.database();
// 检测连接状态
export const connectedRef = db.ref('.info/connected');
const firebaseRef = db.ref(`/comments`);
数据读取:
// 通过缩略名获取评论
const getCommentsByPostSlug = (slug) => {
return new Promise((resolve, reject) => {
firebaseRef
.orderByChild('slug')
.equalTo(slug)
.once('value', (snapshot) => {
const comments = (snapshot.val());
resolve(comments || []);
});
});
};
数据写入:
// comment写入
const addComment = (comment, callback) => {
if (!comment.valid) {
comment.valid = location.host;
}
const id = firebaseRef.push().key;
return db.ref(`/comments/${id}`).set({...comment });
};
数据监听:
const addCommentsChangeListener = (slug, callback) => {
firebaseRef.on('value', (snapshot) => {
const posts = snapshot.val();
callback(posts);
});
};
渲染部分:
const BlogCommentsTemplate = (props) => {
const [comments, setComments] = useState(null);
useEffect(() => {
// 获取评论
getCommentsByPostSlug(slug).then((items) => {
setComments(items);
});
// 监听评论变化
addCommentsChangeListener(slug, (items) => {
setComments(items);
});
}, [slug]);
// 渲染评论内容
return (<Comments comments={comments} />);
实例
可以在这篇文章下面评论,目前支持一级嵌套,仅可回复楼主,样式也和wordpress类似。
安全性
对应完全暴露在网络上的数据库,安全性是首先要考虑的,通常,可以在服务器端通过验证来源网站、约定token等方法,规避一些风险。对于firebase也类似,这部分请参考 Firebase 发布核对清单
对于网页应用:
1、(设置完没什么用,可能需要开登录)为您的网域添加白名单,以防止未经授权的使用:
请前往 https://console.developers.google.com/apis, 在凭据(credentials)下,设置API对应的安全域名
2、配置合适的数据库读写规则,防止意外操作
3、考虑使用身份验证
参考文档
1、数据库规则
2、避免不安全的规则
3、实时数据库的读写操作
4、用firebase建立评论系统