【初心者】Firebase9.8.3におけるAuthenticationとCloud Firestoreの使い方【React】

初めてQiitaに投稿させていただきます。
私はITとは無縁の製造メーカーの営業職31歳で、30歳になってからプログラミングの勉強を始めたような人です。
なのでプロの方々からすると「こいつ何言ってんだ？」みたいな記事かもしれませんが、私自身のアウトプットや備忘録的な側面もあるので、暖かい目で優しいご意見を頂けると幸いです。
基本的に曖昧です！
# 当記事の目的
FirebaseのAuthenticationとCloud FirestoreをReactで使用できるように、できる限り簡潔にまとめる。
#### 環境
"firebase": "^9.8.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
# FirebaseのAuthenticationやCloud Firestoreの全体的なイメージ
最初に、firebaseをreactで扱う際の大まかなイメージを書きます。
１．firebaseを使用するための設定用ファイルを作成する（firebaseへの接続）
２．使用したいfirebseのサービスを設定用ファイルに記載する（firebaseアプリケーションの接続）
３．使用するfirebaseサービスのライブラリを使用したいコンポーネントで読み込む（firebaseアプリケーションの使用）
## １．firebaseを使用するための設定用ファイルを作成する（firebaseへの接続）
基本的にfirebaseの公式に乗っ取れば問題ありません。
xxxは自分専用のやつに変えてください。
```jsx
import { initializeApp } from "firebase/app";

const firebaseConfig = {
  apiKey: "xxx",
  authDomain: "xxx",
  projectId: "xxx",
  storageBucket: "xxx",
  messagingSenderId: "xxx",
  appId: "xxx"
};

const app = initializeApp(firebaseConfig);
```
## ２．使用したいfirebseのサービスを設定用ファイルに記載する（firebaseアプリケーションの接続）
先ほどのファイルにAuthenticationやCloud Firestoreにつなげるための設定をライブラリを読み込んで記載する。
```jsx
import { initializeApp } from "firebase/app";
//getFirestoreでfirestoreと接続できる
import { getFirestore } from "firebase/firestore";
//getAuthでfirebase　authentiateと接続できる
import { getAuth } from "firebase/auth";

const firebaseConfig = {
  apiKey: "xxx",
  authDomain: "xxx",
  projectId: "xxx",
  storageBucket: "xxx",
  messagingSenderId: "xxx",
  appId: "xxx"
};

const app = initializeApp(firebaseConfig);
//読み込んだgetFirestoreとgetAuthに自分の設定を読み込ませて、
//ほかのコンポーネントから呼び出せるようにexportする
export const db = getFirestore(app);
export const auth = getAuth(app);
```
## ３．使用するfirebaseサービスのライブラリを使用したいコンポーネントで読み込む（firebaseアプリケーションの使用）
AuthenticationやCloud Firestoreで分けようと思います。
基本的にメソッドを紹介する形で書いていくほうが個人的にわかりやすいので、そういう風にします。
### （１）authについて
参考元：[https://reffect.co.jp/react/react-crud-firebase-9](https://reffect.co.jp/react/react-crud-firebase-9)
#### createUserWithEmailAndPassword
authとメールとパスワードを渡すことでユーザー登録できる。主にサインイン用コンポーネントで使用する。
例
```jsx
const handleSubmit = async(e) => {
        e.preventDefault()
        try{
            await createUserWithEmailAndPassword(
                auth,
                registerEmail,
                registerPassword
            )
				}catch(error){
            alert('Please enter correctry')
        }
    }
```
#### onAuthStateChanged
authを渡すことで現在の認証状況(currentUser)を取得できる。
認証状況を把握したい時に使用するのでサインインやサインアウト、ログインやマイページなど使い時は多い。
例
```jsx
useEffect(()=>{
        onAuthStateChanged(auth,(currentUser)=>{
            setUser(currentUser)
        })
    },[])

const logout = async() =>{
        await signOut(auth);
        navigate('/login/')
    }
```
#### signInWithEmailAndPassword
ログインすることができる。使い方はcreateUserWithEmailAndPasswordと同じ感じ
例
```jsx
const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      await signInWithEmailAndPassword(
        auth,
        loginEmail,
        loginPassword
      );
    } catch(error) {
      alert("メールアドレスまたはパスワードが間違っています");
    }
  };
```
#### signOut
サインアウトすることができる。
例
```jsx
const logout = async() =>{
        await signOut(auth);
 }
```

### （２）Cloud Firestoreについて
対象へ接続（参照）して、読み書き更新をするイメージな気がします。
参考元：[https://ralacode.com/blog/post/react-firebase-authentication/](https://ralacode.com/blog/post/react-firebase-authentication/)

#### doc
特定のドキュメントへ接続（参照）する
例
```jsx
const userDocumentRef = doc(db, 'users', 'ABCDEF')
```
#### setDoc
ドキュメントへの接続を使用してドキュメントを作成または更新する。
指定したドキュメントが存在すれば更新、なければ作成となる。
docと一緒に利用するのだと思う。
例
```jsx
const handleSubmit = async (event) => {
    event.preventDefault();
    const { name, email } = event.target.elements
    const userDocumentRef = doc(db, 'users', 'ABCDEF');
    const documentRef = await setDoc(userDocumentRef, {
      name: name.value,
      email: email.value,
    });
  };
```
#### collection
特定のコレクションへ接続（参照）する。
例
```jsx
const userDocRef = collection(db,'users')
```
#### addDoc
コレクションへの接続を使用して新たにドキュメントを作成する。
作成したドキュメントのidはランダムになる。
例
```jsx
const handleSubmit = async (event) => {
    event.preventDefault()
    const { name, email } = event.target.elements
    console.log(name.value, email.value)
    const userDocRef = collection(db,'users')
    const docRef = await addDoc(userDocRef, {
      name: name.value,
      email:email.value,
    })
  };
```
#### deleteDoc
ドキュメントへの接続（参照）を使用して削除する。docを使用する。
例
```jsx
const deleteUser = async (id) => {
    const userDocumentRef = doc(db, 'users', id);
    await deleteDoc(userDocumentRef);
  };
```
#### onSnapshot
データベースの更新をリアルタイム（更新することなく）で取得する。
collectionとセットで用いる。
取得したデータはuseStateで保管する。
例
```jsx
const [users, setUsers] = useState([]);
useEffect(() => {
    const colRef = collection(db, "users");
    onSnapshot(colRef, (querySnapshot) => {
      setUsers(
        querySnapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
      );
    });
}, []);
```
#### getDocs
データベースの情報を取得するが、ページを更新させる必要がある。
プロミスオブジェクトを返す。collectionを使用する。
なんでonSnapshotはthenがなくていいのか知りたい（押しえて偉い人）。
例
```jsx
const [users, setUsers] = useState([]);
useEffect(() => {
    const colRef = collection(db, "users");
    getDocs(colRef).then((querySnapshot) => {
    setUsers(
      querySnapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
    );
  });
}, []);

```
この記事が誰かの役に立てば、なんて大それたことは申せませんが、今後ともよろしくお願いいたします。