Gatsby + microCMS + Firestore エラー・不具合集


Gatsby + microCMS + Firestore エラー・不具合集

microCMSからGraphQLでもらってくる記事コンテンツが…

10を超えるとそれ以上取得できない。

原因

microCMSのGET APIはデフォルトで10件まで取得となっている。

解決方法

limitパラメータを与えることで取得件数を増やすことができる。
Gatsbyの場合は、gatsby-config.jsでオプションで変更する。

// gatsby-config.js
   resolve: "gatsby-source-microcms",
    options: {
      apiKey: "xxxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxxxx",
      serviceId: "hogehoge",
      endpoint: "articles",
      query: {
        limit: 100, // ←ここで100件に変更
      }
   },

同一ページをリロードすると中身が表示されない

gatsby developの開発環境では問題ない。しかしgatsby buildの本番環境でページ再読み込みするとコンテンツが表示されない。エラーもなし。

原因

Gatsbyの問題。以下のコード、dangerouslySetInnerHTMLのバグ。

<p
         dangerouslySetInnerHTML={{
           __html: `${article.body}`,
         }}
></p>

解決方法

まだIssue上がりっぱなしだが、回避策として<div>を使う。<p>タグだと起きる問題なのであった。

<div
         dangerouslySetInnerHTML={{
           __html: `${article.body}`,
         }}
></div>

参考:dangerouslySetInnerHTML does not work on production builds


Firestoreのタイムスタンプ型フィールドの表示方法

Firestoreの日付フィールドに現在時間を書き込むとき、
createdat : new Date()
とか
createdat : firebase.firestore.Timestamp.fromDate(new Date())
とかやって書き込むと思うが自動的にタイムスタンプ型(Timestamp型)で書き込まれる。これを読むとき、{item.created}とやってもエラー。

原因

Firestoreの日付型フィールドの仕様が変わった。

解決方法

つぎのようにして読む。

{new Date(item.createdat.seconds * 1000).toLocaleDateString("ja-JP")} {new Date(item.createdat.seconds * 1000).toLocaleTimeString("ja-JP")}

これでこんな風になる。

TypeError: unsubscribe is not a function

Firestoreからデータを読み込むとき、必ずuseEffect()の中でunsubscribe();すると思う。以下はコード例。

// components/comments.js
import React, { useEffect, useState } from 'react'
import firebase from '../../utils/firebase'

const useComments = () => {
      const [items, setItems] = useState([]);

      useEffect(() => {
          const unsubscribe = firebase
          firebase
            .firestore()
            .collection("comments")
            .onSnapshot(snapshot => {
              const data = []
              snapshot.forEach(d => data.push({
                  id: d.id,
                  ...d.data(),
                }));
                setItems(data)
            });
          return () => unsubscribe(); // ← ここ
      }, []); 
      return items;
};

const CommentList = () => {
・・・表示処理・・・
}

常套句だと思う。このコンポーネントを例えば全ページに埋め込んで表示させたいとする。例えばこのように。

//すべてのページ.js
import React from "react"
import CommentList from '../components/Comment'

const AllPages = () => {
 return (
・・・・・・
 <CommentList />  ここ
 )
}

これですべてのページにコメントリストコンポーネントが表示される。しかしこれで他のページに遷移すると

原因

わからない。静的サイトだから?

解決方法

unsubscribe()しない。
return () => unsubscribe();の一文をコメントアウト。

これでいいのだろうか…。結論から言うとGatsbyで動的機能は原則きびしい。

宣伝

microCMSのことは除き、Gatsbyの基本とnode APIの扱いについて踏み込んで解説・ハンズオンした電子書籍を上梓しましたので、よろしければお手に取ってみて下さい。

JAMStackを学ぼう Gatsby, React bootstrap, Netlifyでつくる企業サイト: もうレンタルサーバーはいらない ヤー・ビズテック



GatsbyとmicroCMSを組み合わせてのコーポレートサイト作成手順を解説・ハンズオンした続編を上梓しました。どうぞお手に取ってみて下さい。

JAMStackを学ぼう GatsbyとmicroCMSでつくるコーポレートサイト ~WordPressはもう古い~