Skip to content

Latest commit

 

History

History
273 lines (240 loc) · 7.17 KB

0926_FDS.md

File metadata and controls

273 lines (240 loc) · 7.17 KB

FIREBASE + REACT

  • FIREBASE AUTHENTICATION
    • 인증이나 로그인 같은 것 간단하게 해줌
  • FIREBASE REAL TIME DATABASE
    • 데이터 베이스 바뀌면 자동 컴포넌트 업데이트
  • FIREBASE STORAGE
    • 파일 올릴 때 서버구성 간단하게

실습

채팅app 만들기

git clone https://github.com/paulsoh/fastchatapp.git
yarn //이나 npm install 
yarn start

터미널 창 하나 더 추가

yarn add firebase
yarn add lodash

Firebase 사용

  • 1 Firebase 가입하기
  • 2 프로젝트 추가 눌러서 만들고 const config = {...} 이 부분 복사해서 우리가 만들려는 파일에 추가
  • 3 Firebase 사이트에 Database 메뉴안에 => 규칙
  {
  "rules": {
    ".read": "true",
    ".write": "true"
  }
	}

원래 이 부분"auth != null"을 "true" 로 바꾸고 게시버튼 눌러서 저장 나중에 개발 하면서 다시 원래대로 변경 - DATABASE 기본적으로 인증 요구. 개발할 동안에는 편의를 위해 잠깐 해제

  • 3 Database => 데이터 에서 데이터 값 이름 입력

firebase.js

import firebase from 'firebase';

const config = {
 
  //Firebase 사용.2 위에 복사한 부분 const config = {...} 
}

firebase.initializeApp(config);

export const googleProvider = new firebase.auth.GoogleAuthProvider();

export const database = firebase.database();
export const storage = firebase.storage();
export const auth = firebase.auth();

앱 만들때 로그인 기능 달기

  • Firebase 사이트 Authentication메뉴에서 =>로그인 방법 =>로그인 제공업체에서 원하는 곳 선택

ChatApp.js

import React from 'react';
import {
  database,
  googleProvider,
  auth,
} from './firebase';
import map from 'lodash/map';


const tileClasses = [
  'danger',
  'primary',
  'info',
  'success',
  'warning',
];

export default class ChatApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: '',
      messages: [], 
      currentUser: {
        name: '', // user.displayName
        photoUrl: '', // user.photoURL
        email: '', // user.email
      },
    }
  }

  getMessagesFromDB = () => {
    database.ref("/messages").on('value', (snapshot) => {
      this.setState({
        messages: map(snapshot.val(), (message => message))
      })
    })    
  }

  componentDidUpdate = (prevProps, prevState) => {
    if (prevState.messages.length !== this.state.messages.length) {
      document.body.scrollTop = document.body.scrollHeight;          
    }
  }

  componentDidMount = () => {
    database.ref("/messages").once('value', (snapshot) => {
      this.setState({
        messages: map(snapshot.val(), (message => message))
      })
    })

    auth.onAuthStateChanged((user) => {
      if (user) {
        const currentUser = {};
        currentUser.name = user.displayName;
        currentUser.photoUrl = user.photoURL;
        currentUser.email = user.email;
        console.log('User has logged in!');
        console.log(user);
        this.setState({
          currentUser: currentUser,
        })
        this.getMessagesFromDB();
      } else {
        const currentUser = {};
        currentUser.name = '';
        currentUser.photoUrl = '';
        currentUser.email = '';
        this.setState({
          currentUser: currentUser,
          messages: [],
        })

        console.log("User has logged Out");
      }
    })
  }
  
  onTextChange = (e) => {
    this.setState({
      message: e.target.value,
    })
  }

  loginWithGoogle = () => {
    auth.signInWithPopup(googleProvider)
      .then((user) => {
        console.log(user)
      })
      .catch(error => console.log(error))
  }

  logout = () => {
    auth.signOut().then(() => {}).catch(() => {})
  }

  addMessageToDB = (e) => {
    e.preventDefault(); // 기본 행동 (새로고침)을 막기 위해서 넣어줌
    const currentTime = new Date();
    const message = {
      text: this.state.message,
      time: currentTime.toLocaleTimeString(),
      userName: this.state.currentUser.name,
    }
    database.ref("/messages").push(message)
    .then((e) => console.log(e))
    .catch(e => console.log(e))
    this.setState({
      message: '',
    })
  }

  render() {
    return (
      <div>
        <div
          style={{ backgroundColor: 'white', position: 'fixed', zIndex: 100, display: 'flex', justifyContent: 'center', padding: '15px', width: '100%', }}
        >
          <h1 className="title is-1">챗:앱</h1>
          {this.state.currentUser.name ? (
            <div>
            <figure className="image is-64x64">
              <img src={this.state.currentUser.photoUrl} />
            </figure>
              <span>{this.state.currentUser.email}</span>
              <a onClick={this.logout} className="button is-primary">
                로그아웃
              </a>
            </div>
          ) : (
            <a onClick={this.loginWithGoogle} className="button is-danger">
              구글로 로그인
            </a>
          )}
        </div>
        <div className="container" style={{ paddingTop: '100px', paddingBottom: '100px' }}>
          {this.state.messages.map((message, i) => {
            return (
              <div className="tile is-parent">
                <article className={`tile is-child notification is-${tileClasses[i%5]}`}>
                  <p className="title">{message.text}</p>
                  <p className="subtitle">{message.time}</p>
                  <p className="subtitle">{message.userName}</p>
                  </article>
              </div>
            )
          })}
        </div>
        <div style={{ position: 'fixed', bottom: '0', width: '100%' }}>
          <footer className="footer" style={{ padding: '24px', backgroundColor: 'white' }}>
            <div className="container">
              <div className="content has-text-centered">
                <form onSubmit={this.addMessageToDB}>
                  <div class="field">
                    <div className="control">
                      <input
                        className="input is-large"
                        type="text"
                        placeholder="챗"
                        onChange={this.onTextChange}
                        value={this.state.message}
                      />
                    </div>
                  </div>
                </form>
              </div>
            </div>
          </footer>
        </div>
      </div>
    );
  }
}

suge.sh 사용해서 배포하기

터미널 창에서

npm install --global surge
yarn build
react-scripts build

  • 이렇게 하면 build 폴더 생성됨
  • 결국 배포는 build 폴더만 함
cd build
surge

입력하면 email, password 입력하라고 뜸 입력하면 Success! Project is published and running at 뒤에 주소 나오는데 이 주소를 복사

  • Firebase 사이트에가서 Authentication 메뉴안에 -> 로그인방법 -> 승인된 도메인에 도메인 추가버튼 눌러서 위에 복사한 주소 붙여넣기

  • 브라우저 주소창에 추가한 이 주소 넣으면 뜸

  • 수정사항 있으면 다시 yarn build 하기