1
0

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 3 years have passed since last update.

Reactでアプリを作成しました【9】【LINE clone】

Last updated at Posted at 2022-02-03

環境の準備

①ターミナルでreactアプリケーションを作成する。

$ npx create-react-app <プロジェクト名>
% cd <プロジェクト名>
% npm start

②logo.svg, index.css, App.test.js, reportWebVitals.js
setupTest.js を削除する。

③必要なパッケージをインストールする。

$ npm install @mui/material @emotion/react @emotion/styled
$ npm install @mui/icons-material
$ npm install firebase
$ npm install --save react-firebase-hooks

コンポーネント・ファイル構成

src
├── components
       ├── Line.js
       ├── SendMessage.js
       └── SignIn.js
       └── SignOut.js
├── App.js
├── App.css
├── firebase.js
├── index.js

Firebaseの設定

① プロジェクトの作成する。

image.png

image.png

② アナリティクスを無効にし、『プロジェクトを作成』する。

image.png

③ webボタンを押し、アプリのニックネームを入力し、『アプリを登録』する。

image.png

image.png

④ apiKeyなどをfirebase.jsに編集する。

image.png

firebase.js
//v9の場合、compat/appの中にfirebaseが入っている
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
import "firebase/compat/firestore";

const firebaseApp = firebase.initializeApp({
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
});

//firestoreからテキスト情報をとってくる
const db = firebaseApp.firestore();
//firebaseのauthから認証情報をとってくる
const auth = firebase.auth();
//db, authの変数をどこでも使えるようにする
export { db, auth };

⑤ Authenticationを『始める』する。

image.png

⑥ Sign-in methodでログインプロバイダ『Google』を選択する。

image.png

⑦ 『有効する』『保存』を選択する。

image.png

image.png

⑧ 『データベースを作成する』から『テストモードで開始する』『次へ』をする。

image.png

⑨ Cloud Firestoreのロケーションを設定し、『有効にする』にする。

※ 『asia-northeast3』を選択する。

image.png

⑩『コレクションを開始』を押して、コレクションにIDを付与し、『次へ』をする。

image.png

⑪ ドキュメントIDの『自動ID』を押して、ドキュメントIDを作成する。
⑫ フィールド、タイプ、値を入力する。

※ 今回は、フィールド『text』= タイプ『string』値『Hello』にする。

image.png

⑬ フィールドを追加する。

※今回は、フィールド『createdAt』= タイプ『timestamp』で『追加』する。
※日付と時刻は作成日と作成時刻を入力する。

image.png

⑭ CloudFirestoreの『ルール』を押し、
『 request.time < timestamp.date(2022, 3, 17);』を消し、
『allow read, write: if true』書き換え、『公開』する

image.png

Line.jsを編集する。

src/components/Line.js
import React, { useEffect, useState } from "react";
import SignOut from "./SignOut";
import SendMessage from "./SendMessage";
//dbをfirebaseから受け取る
import { auth, db } from "../firebase";

function Line() {
  //firebaseで作成したmessageの変数を格納する
  const [messages, setMessages] = useState([]);
  //第二引数に[]を入れると初回のマウント時=レンダリングした時1回のみ
  useEffect(() => {
    //データベースにアクセスしてメッセージを受け取る
    db.collection("messages")
      //最新の作成順に並び替える
      .orderBy("createdAt")
      //最大限に表示したい数
      .limit(50)
      //いろんなデータを取得する
      .onSnapshot((snapshot) => {
        //いろんなデータをsetsetMessagesを使って取得する
        //docsの中にいろんな情報が入っていて、mapで取り出す。
        setMessages(snapshot.docs.map((doc) => doc.data()));
      });
  }, []);
  return (
    <div>
      <SignOut />
      <div className="messages">
        {/* messagesの中から、map関数で呼び出す */}
        {messages.map(({ id, text, photoURL, userid }) => (
          <div>
            {/* map関数を使う場合、どの関数を取り出すか定める必要があるので divタグに必ずidを付ける */}
            <div
              key={id}
              //   ログインしているユーザーでクラスを変えることができる
              className={`message ${
                userid === auth.currentUser.userid ? "sent" : "received"
              }`}
            >
              {/* 自分のアイコン */}
              <img src={photoURL} alt="" />
              {/* textを取得 */}
              <p>{text}</p>
            </div>
          </div>
        ))}
      </div>
      <SendMessage />
    </div>
  );
}
export default Line;

SendMessage.jsを編集する

src/components/SendMessage.js
import React, { useState } from "react";
import { db, auth } from "../firebase";
import firebase from "firebase/compat/app";
import { Input } from "@mui/material";
import SendIcon from "@mui/icons-material/Send";

const SendMessage = () => {
  //form内に入力したメッセージを別の変数として格納する
  const [message, setMessage] = useState("");
  function sendMessage(e) {
    //文字を入力して、エンターキーを再ロードされない
    e.preventDefault();
    //authから現在ログインユーザーcurrentuserから取ってくる
    const { photoURL, userid } = auth.currentUser;
    //dbのコレクションの中の messages をaddする
    db.collection("messages").add({
      text: message,
      photoURL,
      userid,
      createdAt: firebase.firestore.FieldValue.serverTimestamp(),
    });
    //enterキーを押した後、"メッセージを入力"が表示されない
    setMessage("");
  }
  return (
    <div>
      <form onSubmit={sendMessage}>
        <div className="sendMessage">
          <Input
            style={{
              width: "78%",
              fontSize: "15px",
              fontWeight: "550",
              marginLeft: "5px",
              marginBottom: "-3px",
            }}
            placeholder="メッセージを入力してください"
            type="text"
            onChange={(e) => setMessage(e.target.value)}
            value={message}
          />
          <SendIcon style={{ color: "#7AC2FF", marginLeft: "20px" }} />
        </div>
      </form>
    </div>
  );
};

export default SendMessage;

SignIn.jsを編集する

src/components/SignIn.js

import React from "react";
import { Button } from "@mui/material";
import firebase from "firebase/compat/app";
import { auth } from "../firebase";

const SignIn = () => {
  //Googleでログインする
  function signInWithGoogle() {
    //providerの変数を用意する
    //firebase.auth.GoogleAuthProviderは、Google認証のproviderが使える
    const provider = new firebase.auth.GoogleAuthProvider();
    //firebase.jsの中にauth認証の中にsignInWithPopupが入っていて、用意したproviderを入れる
    auth.signInWithPopup(provider);
  }
  return (
    <div>
      <Button onClick={signInWithGoogle}>Googleでログインする</Button>
    </div>
  );
};

export default SignIn;

SignOut.jsを編集する

src/components/SignOut.js
import { Button } from "@mui/material";
import React from "react";
import { auth } from "../firebase";
import CallIcon from "@mui/icons-material/Call";

const SignOut = () => {
  return (
    <div className="header">
      <Button
        onClick={() => auth.signOut}
        style={{ color: "white", fontSize: "15px" }}
      >
        SignOut
      </Button>
      {/* 現在ログインしているユーザー名 */}
      <h3>{auth.currentUser.displayName}</h3>
      <CallIcon />
    </div>
  );
};

export default SignOut;

App.cssを編集する

App.css
body {
  background-color: #93aad4;
  margin: 0;
  padding: 0;
}

.header {
  background-color: #222a41;
  color: white;
  height: 35px;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

App.jsを編集する

App.js
import "./App.css";
import SignIn from "./components/SignIn";
import Line from "./components/Line";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth } from "./firebase.js";

function App() {
  //user情報を変数に入れる
  const [user] = useAuthState(auth);
  //userがいるかどうか ⇨ いる場合はサインインする
  return <div>{user ? <Line /> : <SignIn />}</div>;
}

export default App;

index.jsを編集する

index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

参考サイト

[ReactでLINEクローンの作り方 - React×Firebaseチュートリアル]
(https://www.youtube.com/watch?v=Js9BsBsczE8)

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?