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

ChatGPTでアプリ開発記 20250503

Posted at

ログイン機能の実装

(1)Firebaseプロジェクトを作る

1.Firebase Console でプロジェクト作成
2.「Authentication」→「ログイン方法」→以下を有効化:

  • メール/パスワード
  • Google

3.ReactアプリにFirebaseをインストール
スクリーンショット 2025-05-02 7.18.31.png

(2) Firebase設定ファイル作成(firebase.js)

firebase.js
// Firebase アプリの初期化に必要な関数をインポートします。
// これにより、Firebase プロジェクトと React アプリが接続されます。
import { initializeApp } from "firebase/app";

// irebaseの認証機能に関する関数やクラスをインポートします。
// getAuth → Firebase認証システムを使用するための関数
// GoogleAuthProvider → Googleログインのためのプロバイダー(設定)
import { getAuth, GoogleAuthProvider } from 'firebase/auth';

// あなたのFirebaseプロジェクトと通信するための設定情報です。
// Firebaseのコンソールからコピーした構成情報がここに入ります。
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};

// Firebaseアプリを初期化します。
// このコードにより、上記の構成情報で Firebase を使う準備が整います。
const app = initializeApp(firebaseConfig);

// 認証システムのインスタンスを生成し、他ファイルでも使えるように「export(外部公開)」します。
// 他のファイル(たとえば Login.js)からこの auth を使ってログイン操作ができます。
export const auth = getAuth(app);

// Googleログインを行うための「プロバイダーオブジェクト」を生成し、他ファイルでも使えるように公開します。
// このオブジェクトを使って、Googleログインができるようになります。
export const googleProvider = new GoogleAuthProvider();

(3)ログイン画面コンポーネントの作成

login.js
// Reactの基本機能と、コンポーネント内で状態(state)を持つための useState フックを読み込んでいます。
import React, { useState } from 'react';

//  firebase.js でエクスポートした Firebase 認証インスタンスと Googleログイン用プロバイダーを読み込みます。
import { auth, googleProvider } from './firebase';

//  Firebase Authentication のログイン/登録機能に必要な関数を読み込んでいます。
import {
  signInWithEmailAndPassword,
  createUserWithEmailAndPassword,
  signInWithPopup,
} from 'firebase/auth';

//  Login コンポーネントの定義です。
// 親コンポーネント(App.js)から onLogin 関数を受け取っています。ログイン成功後に実行します。
function Login({ onLogin }) {

// メールアドレスとパスワードの入力状態(state)を管理しています。
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const loginEmail = async () => {
    try {
      await signInWithEmailAndPassword(auth, email, password);
      onLogin();
    } catch (e) {
      alert(e.message);
    }
  };

  const signupEmail = async () => {
    try {
      await createUserWithEmailAndPassword(auth, email, password);
      onLogin();
    } catch (e) {
      alert(e.message);
    }
  };

  const loginGoogle = async () => {
    try {
      await signInWithPopup(auth, googleProvider);
      onLogin();
    } catch (e) {
      alert(e.message);
    }
  };

  return (
    <div>
      <h2>ログイン/登録</h2>
      <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="メール" />
      <p><input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="パスワード" /></p>
      <div>
        <button onClick={loginEmail}>ログイン</button> &nbsp;&nbsp;
        <button onClick={signupEmail}>登録</button> &nbsp;&nbsp;
        <button onClick={loginGoogle}>Googleでログイン</button>
      </div>
    </div>
  );
}

export default Login;

(4)Appコンポーネントに認証統合

App.js
// Reactの状態管理(useState)と副作用処理(useEffect)を使う準備です。
// useEffectは、関数コンポーネントで副作用(DOM操作、API通信など、UI以外で処理を行うこと)を管理するためのフックです。
import React, { useState , useEffect} from 'react';

// Firebase の認証状態監視とログアウト処理をする関数を読み込みます。
import { auth } from './firebase';

// firebase.js から Firebase 認証インスタンスを読み込みます。
import { onAuthStateChanged, signOut } from 'firebase/auth';

// 自作の Login.js コンポーネントを読み込みます(ログイン画面)。
import Login from './login';


function App() {

//  現在ログインしているユーザーを保持するための state です。未ログイン時は null。
  const [user, setUser] = useState(null);
  
  const [text, setText] = useState('');
  const [posts, setPosts] = useState([]);

// Firebase のログイン状態を常に監視します。
  useEffect(() => {

// user がログインしていれば setUser(user) で状態更新
  const unsub = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
    });
    return () => unsub();
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    if (text.trim() === '') return;

    const now = new Date();
    const formattedTime = now.toLocaleString('ja-JP', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    });


    const newPost = {
      text: text,
      time: formattedTime,
      likes: 0,
      user: user?.email,
    };

    setPosts([newPost, ...posts])
    setText('');
  };

  const handleLike = (index) => {
    const updated = [...posts];
    updated[index].likes += 1;
    setPosts(updated);
  }

  const handleDelete = (index) => {
    setPosts(posts.filter((_, i) => i !== index));
  };

// ユーザーが未ログインなら、ログイン画面を表示します。
// ログイン成功時に setUser を実行することで、投稿画面に遷移します。
  if (!user) {
    return <Login onLogin={() => { }} />;
  }

  return (
    <div style={{ padding: '2rem', fontFamily: 'sans-serif' }}>
      <h1>SNS</h1>
      <p>ようこそ{user.email} さん <button onClick={() => signOut(auth)}>ログアウト</button></p>

      <form onSubmit={handleSubmit}>
        <textarea
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="今なにしてる?"
          rows="4"
          style={{ display: 'block', width: '100%', marginBottom: '1rem' }}
        />
        <button type="submit">投稿する</button>
      </form>

      <div style={{ marginTop: '2rem' }}>
        <h2>投稿一覧</h2>
        {posts.map((post, index) => (
          <div key={index} style={{ padding: '1rem', borderBottom: '1px solid #ccc' }}>
            <div style={{ fontSize: '0.8rem', color: '#666' }}>{post.time} - {post.user}</div>
            <div>{post.text}</div>
            <button onClick={() => handleLike(index)}>❤️ いいね ({post.likes})</button>
            <button onClick={() => handleDelete(index)} style={{ marginLeft: '1rem', color: 'red' }}>🗑️ 削除</button>
          </div>
        ))}
      </div>
    </div >
  );
}

export default App;

(5)操作画面

画面収録-2025-05-02-8.27.41.gif

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