PaPaPointアプリ【合計ポイント表示編②】

2020/11/08

PaPaPointアプリ【CloudFunctions実装編】」でFirestoreからデータ取得できるようになったので,「PaPaPointアプリ【合計ポイント表示編①】」の続きをやっていきます。

合計ポイント表示機能

合計ポイント表示編①ではソース上にベタ書きしたポイントを表示させるところまで完成しています。
今日はFirestoreからデータを取得して,それを表示させます。

PaPaPointアプリ【CloudFunctions実装編】で作ったFunctionsへHttpリクエストしてデータを取得します。 HttpリクエストするにはAxiosかfetch()を使用する必要があります。
むやみにライブラリを増やすのも混乱の元になりそうなのでとりあえず今回はfetch()を使ってみることにします。

カスタムフックの作成

カスタムフックを使ってデータ取得ロジックを切り出しておきます。

import { useEffect, useState } from 'react';

const API =
  'https://asia-northeast1-xxxxxxxxx.cloudfunctions.net/totalPoints';

const useTotalPoints = () => {
  const [totalPoints, setTotalPoints] = useState<number>();

  useEffect(() => {
    (async () => {
      const response = await fetch(API).then((res) => res.json());
      setTotalPoints(response.data[0].point);
    })();
  });

  return totalPoints;
};

export default useTotalPoints;

フロントの方でデータ整形してるので汎用性のかけらもないですね。
Functionsのリファクタリングしないとです。。。

データ取得

合計ポイント表示画面用のコンポーネントではベタ書きしていたところを先程作ったカスタムフックを用いてデータを取得してみます。

export const TotalPointsDisplay: FC = () => {
  const classes = useStyles();
  const unit = <span className={classes.unit}>papapo</span>;
  const totalPoints = useTotalPoints();
  return (
    <Card className={classes.root}>
      <CardHeader title="現在の合計PapaPointは" disableTypography />
      <CardContent className={classes.content}>
        {totalPoints}
        {unit}
      </CardContent>
    </Card>
  );
};

これでデータ取得できるぜぇと思ったのも束の間。
CORS問題にぶち当たりました。

CORS問題

CORSとは別のリソースにアクセスする際の決まりごと?みたいな感じですかね?雰囲気で理解しています。
APIとクライアントアプリのオリジン(スキーム,ホスト,ポートの組み合わせ)が異なることでAPIがリソースを返すのを制限しているという認識です。
間違ってたら教えて下さい。

なので,API側にアクセスを許可するオリジンとメソッド,ヘッダーを追記してやります。

export const totalPoints = functions
  .region('asia-northeast1')
  .https.onRequest(async (req, res) => {
    const snap = await admin.firestore().collection('total_point').get();
    const data = snap.docs.map((doc) => doc.data());

    res.set('Access-Control-Allow-Origin', 'http://localhost:3000');    res.set('Access-Control-Allow-Methods', 'GET');    res.set('Access-Control-Allow-Headers', 'Content-Type');    res.send({ data });
  });

Access-Control-Allow-Originではリクエスト元(今回でいうとPaPaPointアプリ)を値にセットしてやります。(↑はローカル環境の値になってる)

これで無事にデータの取得が出来ました。

まとめ

Reactで詰まるというより連携の部分,Firebaseで詰まることのほうが多いです。
とはいえバックエンドも開発するよりかはだいぶ工数削減出来ている気はします。
ソースも色々試しているととっちらかってくるので気づいたときにリファクタリングしないとです。

それではまた明日。


書いた人: こへ
音楽と漫画と読書とアニメとスノボが好き。多趣味でいろんなことに興味有ります。 誰しもが一度は使った事があるもののIoT開発をしてます。
Twitterフォローお願いします。