1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React + Redux + Firebaseで「プログラミング独学ロードマップ」を共有できるサービスを作った。

Posted at

こんにちは、現在転職活動中のけんぞうです。
先日「React+Redux+Firebase」の技術スタックで、Devmap | 独学ロードマップ共有サービスを作ってみました。

この記事では、感想などを書きつつ、振り返りをしてみようかと思います。

コードはこちら

サービスの紹介

上記の動画のようなアプリケーションを作りました。僕自身が転職に向けてプログラミングを独学してきた過程を残しつつ、他の人の独学方法も知れたらいいなーとおもい、実装しました。

具体的には以下の項目が実装済みです。

  • Google / Twitter / Facebook認証ログイン
  • Cloudinaryを用いて動的にアイキャッチ画像を生成
  • Cloud Functionsを用いて動的にOGP画像を生成

モチベーション

すごく個人的なことなのですがツイートの通り6/12が誕生日だということに、ちょうど1週間前に気が付きまして、「せっかくだったら区切りも良いし1週間で何か作ってみるかー」と腰をあげて、1週間かけてガリガリ実装しました。

Reactでしっかりしたアプリケーションを作るのは今回が初めてだったので、手探りな部分もあったのですが、ひとまず1週間で形になったので一安心です。

実装で苦戦したところ

時間がたつと苦戦したところを忘れてしまうので、備忘録として残しておきたいと思います。

1.認証ログイン

Firebaseでの認証をアプリケーションに取り入れているのですが、signInWithPopupsignInWithRedirect のどちらを採用するかで時間がかかってしまいました、、

僕が動かしてみた範囲では、上記の2つには以下のような違いがありました。

  • signInWithRedirect:認証と同時にusers collectionが自動で生成されて、ユーザー情報が格納される。これが便利なんだけど、リダイレクトした画面が数秒間真っ白になってしまう問題が発生した。
  • signInWithPopup:認証と同時にユーザー情報の保管は行われないが、画面真っ白問題は解消される。

結果的には、「signInWithPopupを採用しつつ、users collectionにデータを格納する」という実装をおこないました。

Login.js

loginwithTwitter = () => {
    this.setState({
      clicked: !this.state.clicked // Loading Skeleton
    });
    const provider = new firebase.auth.TwitterAuthProvider();
    firebase
      .auth()
      .signInWithPopup(provider)
      .then(response => {
        this.props.loginAuth(response);
      });
  };


authActions.js

// Login with authentification
export const loginAuth = res => {
  return (dispatch, getState, { getFirestore }) => {
    const firestore = getFirestore();
    // const authorId = getState().firebase.auth.uid;
    firestore
      .collection("users")
      .doc(res.user.uid)
      .set({
        // id: res.user.uid,
        displayName: res.user.displayName,
        avatarUrl: res.user.photoURL
      })
      .then(() => {
        dispatch({ type: "LOGIN_SUCCESS" });
      })
      .catch(err => {
        dispatch({ type: "LOGIN_ERROR", err });
      });
  };
};

2.動的なOGP画像の設定

そもそもSPAを開発すること自体が初だったので、「クローラがJavascriptを実装しないから、react-helmetなどを使ってメタタグを書き換えても、TwitterCardが切り替わらない」という事情をしらず、動的なOGP画像設定にかなり時間を食ってしまいました、、

最終的には、firebaseでサーバレスなSPAアプリを作った話②を参考にさせていただきながら、Cloud Functionsでメタタグを挿入するという方法を採用しました。

上記記事の内容とほぼコードは一緒ですので、説明は割愛させていただきます。

index.js

const fs = require("fs");
const path = require("path");
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.returnHTMLWithOGP = functions.https.onRequest((req, res) => {
  fs.readFile("./hosting/index.html", "utf-8", (e, html) => {
    const overviewId = req.path.split("/")[2];
    const firestore = admin.firestore();
    try {
      firestore.settings({ timestampsInSnapshots: true });
    } catch (error) {
      // ignore
    }
    firestore
      .collection("overviews")
      .doc(overviewId)
      .get()
      .then(doc => {
        const overview = doc.data();
        html = html.replace(
          html.match(/<title>.*<\/title>/),
          `<title>${overview.title} | ${
            overview.authorName
          }さんのロードマップ</title>`
        );
        html = html.replace(
          html.match(/<meta property="og:image"[^>]*>/),
          `<meta property="og:image" content="${overview.eyeCatchImg}">`
        );
        html = html.replace(
          html.match(/<meta property="og:title"[^>]*>/),
          `<meta property="og:title" content="${overview.title} | ${
            overview.authorName
          }さんのロードマップ">`
        );
        html = html.replace(
          html.match(/<meta property="og:url"[^>]*>/),
          `<meta property="og:url" content="https://devmap.work/overviews/${
            overview.key
          }">`
        );
        res.set("Cache-Control", "public, max-age=3600, s-maxage=3600");
        res.status(200).send(html);
        return overview;
      })
      .catch(e => {
        res.status(200).send(html);
        throw e;
      });
  });
  return 0;
});

というわけで、以上です。
Devmap | 独学ロードマップ共有サービス

よかったらのぞいてみてください。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?