1. Firebase Database의 특징

2. Firebase Database 보안 규칙 설정

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

3. Firebase Database 예시

App.js

import { useEffect, useState } from "react";
import AppRouter from "components/Router";
import { authService } from "fbase";

function App() {
  const [init, setInit] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [userObj, setUserObj] = useState(null);

  useEffect(() => {
    authService.onAuthStateChanged((user) => {
      if (user) {
        setIsLoggedIn(true);
        setUserObj(user);
      } else {
        setIsLoggedIn(false);
      }
      setInit(true);
    }); // 사용자 로그인 상태의 변화를 관찰한다.
  }, []);
  // console.log(authService.currentUser);
  // setInterval(() => {
  //   // console.log(authService.currentUser); // 인증하는데 시간이 걸린다.
  // }, 2000);
  // console.log(init); // authService.onAuthStateChanged 때문에 init의 상태 값이 true로 바뀌면서 <AppRouter> 컴포넌트가 나오게 된다.
  return (
    <>
      {init ? (
        <AppRouter isLoggedIn={isLoggedIn} userObj={userObj} />
      ) : (
        "Initializing ..."
      )}
      <footer>&copy; {new Date().getFullYear()} Nwitter</footer>
    </>
  );
}

export default App;

Router.js

import React from "react";
import { HashRouter as Router, Route, Switch } from "react-router-dom";

import Auth from "routes/Auth";
import Home from "routes/Home";
import Profile from "routes/Profile";
import Navigation from "./Navigation";

const AppRouter = ({ isLoggedIn, userObj }) => {
  return (
    <Router>
      {isLoggedIn && <Navigation />}
      <Switch>
        {isLoggedIn ? (
          <>
            <Route exact path="/">
              <Home userObj={userObj} />
            </Route>
            <Route exact path="/profile">
              <Profile />
            </Route>
          </>
        ) : (
          <Route exact path="/">
            <Auth />
          </Route>
        )}
      </Switch>
    </Router>
  );
};

export default AppRouter;

Home.js

// import { dbService } from "fbase";
import Nweet from "components/Nweet";
import { dbService } from "fbase";
import {
  getDocs,
  addDoc,
  collection,
  onSnapshot,
  doc,
} from "firebase/firestore";
import React, { useEffect, useState } from "react";

const Home = ({ userObj }) => {
  const [nweet, setNweet] = useState("");
  const [nweets, setNweets] = useState([]);
  // const getNweets = async () => {
  //   const dbnweets = await getDocs(collection(dbService, "nweets"));
  //   dbnweets.forEach((document) => {
  //     // console.log(document.data());
  //     const nweetObject = {
  //       ...document.data(),
  //       id: document.id,
  //     };
  //     setNweets((prev) => [nweetObject, ...prev]);
  //   });
  // }; // 예전 방식 (snapshot을 이용한 방식이 좀 더 간편하다 , 또한 더 적게 re-render하기 때문에 더 빠르게 실행되도록 만들어 준다.)
  useEffect(() => {
    // getNweets(); // 예전 방식
    onSnapshot(collection(dbService, "nweets"), (snapShot) => {
      const nweetArray = snapShot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));

      setNweets(nweetArray); // 더 적은 렌더링으로 데이터가 실시간으로 변한다.
    });
    // snapshot은 데이터베이스에 무슨일이 일어날 때, 알림을 받는다.
    // 여기서는 firestore의 nweets 컬렉션에 무슨 일이 발생할 경우 콜백함수를 실행한다.
  }, []);
  // console.log(nweets);
  const onSubmit = async (e) => {
    e.preventDefault();
    await addDoc(collection(dbService, "nweets"), {
      text: nweet,
      createdAt: Date.now(),
      creatorId: userObj.uid, // 로그인할 때  유저정보를 받아온다.
    });
    setNweet("");
  };
  const onChange = (e) => {
    const {
      target: { value },
    } = e;
    setNweet(value);
  };
  return (
    <div>
      <form>
        <input
          type="text"
          placeholder="What's on your mind"
          maxLength={120}
          value={nweet}
          onChange={onChange}
        />
        <input type="submit" value="Nweet" onClick={onSubmit} />
      </form>
      <div>
        {nweets.map((nweet) => {
          return (
            <Nweet
              key={nweet.id}
              nweetObj={nweet}
              isOwner={nweet.creatorId === userObj.uid}
            />
          );
        })}
      </div>
    </div>
  );
};

export default Home;