写这篇文章之前,本人也了解过其他网站的做法,大部分都是基于 Leancloud 来实现,使用谷歌 Firestore(Firebase)来做的很少。国内版 Leancloud 需要实名认证,最近还需绑定自己的域名(详情)。一种方案就是使用国际版来替代,此版本只需要绑定邮箱和手机号,参考:这篇文章
主要是本人比较排斥这样搜刮隐私的行为,So 经过几次尝(tou)试(ji)无果后,果断放弃!
关于 Leancloud 的相关实现,可以参考下边这篇文章,精简实用,本文也在此基础上作了参考。
注意:使用 leancloud 这功能时,有以下两个前提
1、主题配置文件开启 leancloud_visitors,并设置 app_id 和 app_key:
1 | leancloud_visitors: |
配置文件也有 “Show number of visitors to each article” 这个说明,开启这个才能统计每篇文章的的访客数(阅读量),排行榜功能是需要用到这个数值的,所以得开启
2、leancloud 应用中创建 Class
登录leancloud控制台创建应用(也可以用已经创建好的),在所选择应用的存储选项下创建Class按钮,新建一个class,class名一定要是Counter,其它配置默认即可。若是不创建这个Class的话,上一步中的访客数(阅读量)就一直为空,排行榜功能就不能正常工作。
创建后正常访问:

以上两点提示,重要!!!
开始进入正题:Firestore
主题配置文件,已经提前预配了 firestore:

是不是已经给你提示了呢?而且官方文档也提到过,一共分为两步:
1、注册

2、配置

Firebase 属于谷歌的,确保你能访问:https://console.firebase.google.com (tips:科学上网)
注册
可以直接使用 Google 帐号登录,没有的自行进行注册,此步骤略过。登录成功后,点击网页右上角:转到控制台
添加项目
输入项目名称,比如是 leafjame2019814, 点击继续,默认配置即可,完成后还可以再修改。

创建项目完成后,点击网页左侧 setttings 按钮,如图:

可查看到自己的项目 ID和网络 API 密钥,这就是 next 主题配置文件中提到的 projectId 和 apiKey

创建数据库
创建完项目后,接着需要创建存储数据的地方,如下图所示:

有两种选项,自己用的话,选择以测试模式开始,就可以。

如果选择以锁定模式开始,后续自己通过 js api 的方式写入时会提示没有权限
下一步设置 Cloud Firestore 位置,有以下好几种,分为多域性和区域性。具体区别可查看文档,默认选择 nam5 (us-central) 即可,点击完成,等待分配 Database。

完成后显示是这样的,现在还没有数据。
可参考Cloud Firestore 使用入门,文档还是很全的
配置文章阅读量
做完上边的操作后,接着就是把代码集成到自己的项目中了。
在 next/layout/_third-party/analytics/firestore.swig 中,其实已经实现了文章阅读量的功能,只需要经过本文以上的操作,然后在 next/_config.yml 文件,启用 firestore:

里面的 apiKey 和 projectId 就是上文中创建的,collection:集合 ID,下边会讲到。
这个功能经过配置后,可用于文章的阅读次数了,当文章未被查看时,效果是这样的:

此时 Firebase 中 Database 下还没有数据,当浏览这篇文章后,阅读次数加 1 了,如图:

再打开 Firebase,你会发现,也有数据了:

articles 就是上边配置的 collection 的值,即:集合 ID
这控制台能对集合、文档、字段、值进行操作,比如设置阅读量啦什么的~
设置开发环境
每个页面的阅读量有了,不过我们要做的是排行榜啊,得把所有的页面汇总排序。而且刚才的 Database 里存的数据也没有 URL 等等这些信息呀,接下来要写代码了。
新增如下的页面——「热榜」,我想大家都会了吧,不细说了。

在这个 index.md 中,引入要用到的 Firebase 代码,可参照官方文档进行。
之前我想直接在此 md 文件中引入 firestore.swig,但启动一直报错。。(应该是没配置对的缘故)
报错截图如下:

多次改路径尝试无果后,我觉定在 md 文件中再次引入依赖的 js 代码。
index.md 完整代码如下:
1 |
|
1、引入的 js 版本最好和 firestore.swig 中的保持一致
2、记得把 apiKey 和 projectId 换成你自己的。。
3、orderBy 这是是按 Database 中 articles 集合的 count 值降序排序
4、limit 限制返回的结果集数量
tips:Firebase 官方网站上,可全文搜索想要结果
参考文档: Firebase 读取数据、 Firebase 对数据进行排序和限制数量、 github 上 firestore 相关 JS 操作方法
完成以上步骤后,访问热榜界面,就能出现以下界面了:

文章排行有了,但是点击文章要跳转的链接还没有呢。我们也看到了,Firebase 只保存了每个文章访问量 count 值,没有存文章 url 信息。这就是接下来要解决的问题。
保存文章url地址
前文说过,Next 整合了 firestore,那只能实现记录每篇文章浏览量的功能,要做热榜,似乎不满足需求啊,得改代码。
修改 next/layout/_third-party/analytics/firestore.swig,主要修改的地方有三处:
修改文章页判断逻辑
以 firestore.swig 之前的代码来做排行榜功能时,发现不止文章出现在排行榜页面,连左侧点击过的链接,比如分类、标签、归档等等的链接也会显示在排行榜页面。
后来博主经过多次调试、阅读代码后,发现了问题所在,原因就出现在现有的文章页和非文章页判断逻辑上:

这个逻辑只能适用于单篇文章的阅读次数统计。。不能满足我们现在的需求了,代码修改如下:
1 | //https://hexo.io/zh-tw/docs/variables.html |
修改前后对比如下:

注意了:
1 | var indexPath = 'index.html'; //首页链接 |
这是我在站点配置文件中修改后的结果

之前的 permalink: :year/:month/:day/:title/,在做 SEO 优化改成了 permalink: :title.html,所以这里能直接用来做判断了。当然你不改的话,这里的 if 判断就得改成你现在的逻辑。
修改getCount方法
我也尝试过在 articles.doc(title) 中追加设置链接的方法,参考了 Github,比如:
1 | articles.doc(title).set({'uri': urlPath, 'url': urlFullPath}); |
不过这样操作后,在 getCount 方法中就会出现其它的错误,改动比较多,偷懒一下,我就把 url 地址直接以参数的形式传递到 getCount 方法
1 | getCount(doc, urlFullPath, true) |
这样改动的就相对少了。

这里用了 window.localStorage 来保存整个网站的数据,以 title 为 key,数据没有过期时间,直到手动去删除。
修改文章阅读次数样式(非必须)
最后的修改是为了改下文章阅读次数的样式
将 firestore.swig 中的 $('.post-meta') 替换成 $('.post-wordcount');将图标 $('<i>').addClass('fa fa-users') 替换成 $('<i>').addClass('fa fa-eye'),效果如下:

附上 firestore.swig 完整代码:
1 | {% if theme.firestore.enable %} |
结尾
至于热榜页面的样式布局,可在其 index.md 文件中修改即可
经过博主三四天攻坚,以参阅 Google 官方文档为主,至此,文章热榜功能已经全部完成!👏👏👏
最终效果:

基于 Firestore 做的排行榜也有个缺点,对于不能访问谷歌的用户来说,这个页面是不能正常显示的。
虽然 Firebase 具有离线访问数据功能,不过这是针对短期不能联网的情况。
如果需要做到国内用户普遍都能访问,那好像就得依赖于 Leancloud 实现了,不知道大家有什么其他方案,欢迎留言讨论。
(本文完)

