firebase를 시작해보자

firebase를 시작해보자

firebase란

파이어베이스는 2011년 파이어베이스사가 개발하고 2014년 구글에 인수된 모바일 및 웹 애플리케이션 개발 플랫폼입니다. (위키백과)
파이어베이스는 클라우드 서비스를 제공해주며 동시에 백엔드의 기능을 가지고 있습니다.

필자가 파이어베이스를 사용하게 된 계기는 웹사이트를 만들고 싶은데 서버가 필요했고,
서버구축을 할줄 모르는 상태에서 파이어베이스는 호스팅, 데이터베이스, 스토리지, 인증, FCM 등을 쉽게 사용할수 있게 해기 때문에 파이어베이스를 선택하였습니다.

firebase 환경 설정

1) firebase 프로젝트 만들기
우선 firebase를 사용하려면 당연히 https://firebase.google.com에 접속을 해줍니다.
그 후 회원가입 or 로그인을해 주시고 console(콘솔)로 이동을 해줍니다. (우측 상단에 콘솔로 이동 링크)

콘솔 페이지로 이동후 새 플젝트 만들기를 해주시면 파이어베이스 프로젝트가 생성이 완료가 됩니다. ( 프로젝트 생성되는데 약간의 시간이 걸림)
생성이 완료가 되면 내가 만든 프로젝트 콘솔 페이지가 아래의 그림과 같이 나타나게 됩니다.
firebase

마지막으로 첫화면에서 웹앱 추가 버튼을 클릭하여
firebase
앱 닉네임을 등록하면 나의 앱이 등록되며
firebase
firebase SDK와 해당 앱의 firebaseConfig 값이 부여되어 보여줍니다.
firebase

이제 여러분의 프로젝트에 추가할 firebase 프로젝트가 기본적으로 준비되었습니다.
마지막으로 SDK 추가 및 firebaseConfig 초기화에 대해 설명을 하고 기능에 대해 설명 및 사용법을 알아보겠습니다.

firebase SDK 추가 및 firebaseConfig 초기화

우선 위의 환경설정 마지막에 나온 firebase SDK 및 firebaseConfig를 본인의 프로젝트에 추가 및 초기화 해주도록합니다.

SDK 추가

SDK를 추가하는 방식으로

  1. 호스팅 URL에서 추가
  2. CDN에서 추가
  3. 모듈 Bundler 사용
  4. Node.js앱

이렇게 4가지 방식이 존재하고, 이 글에서는 모듈 Bundler를 사용하여 추가 해 보도록 하겠습니다.
(* 환경설정 마지막에 나온 firebase SDK는 2번 방법 )

1
2
3
4
5
6
7
8
9
npm init
npm install --save firebase

// firebase 앱이 항상 필요합니다.
import * as firebase from "firebase/app";

// 사용할 firebase 기능 추가
import "firebase/auth";
import "firebase/firestore";

firebaseConfig 초기화

SDK를 추가했으면 이제 firebase의 정보를 본인의 프로젝트 정보로 초기화 해줍니다.

1
2
3
4
5
6
7
8
9
10
11
const firebaseConfig = {
apiKey: "xxxxxxxxxx",
authDomain: "xxxxxxxxxx.firebaseapp.com",
databaseURL: "https://xxxxxxxxxx.firebaseio.com",
projectId: "xxxxxxxxxx",
storageBucket: "xxxxxxxxxx.appspot.com",
messagingSenderId: "xxxxxxxxxx",
appId: "xxxxxxxxxx"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);

  • firebaseConfig의 값은 위에서 만든 본인의 firebase앱의 정보를 넣어주면 됩니다.

여기까지 되셨다면 SDK추가와 config 초기화 까지 완료된것입니다.
이제부터는 firebase 기능에 대하여 설명 및 사용법을 알아보겠습니다.

firebase 기능

이 글에서는 firebase의 기능 중

1
2
3
1. Authentication(인증)
2. Database(데이터베이스 - 예시는 읽기만)
3. Storage(저장소 - 예시는 읽기만)

3가지 기능에 대해 알아보겟습니다.

Authentication(인증)

파이어베이스는 인증 시스템을 지원하기때문에 로그인 기능을 추가할 수 있습니다.
인증방법의 종류에는 아래와 같은 인증 방법이 있습니다.

  • 이메일/비밀번호 (사용자 직접 등록)
  • 전화
  • Google
  • Play 게임
  • 게임센터
  • Facebook
  • Twitter
  • Github
  • Yahoo
  • Microsoft

이 글에서는 사용자를 직업 등록하는 방법에 대해 설명하겠습니다.
우선 사용자 등록을 합니다.( 아주 간단합니다. )
자신의 firebase 프로젝트 console화면의 Authentication 탭에 들어가보면 사용자, 로그인방법, 템플릿, 사용량 이렇게 4가지의 메뉴가 존재하는데
사용자 탭에서 사용자를 추가해주도록합니다.

firebase

위처럼 firebase에 로그인 아이디와 비밀번호를 입력하여 사용자를 추가한 후 로그인 방법 탭에서 이메일/비밀번호를 활성화 해준 후
본인의 코드에서 아래와 같이 firebase.auth().signInWithEmailAndPassword(email, pwd)를 호출해주면
성공시 실패시 로직을 작성할 수 있게 됩니다.
( firebase.auth().signInWithEmailAndPassword(email, pwd) 는 Promise 반환 )

1
2
3
4
5
6
7
8
9
import * as firebase from "firebase";
firebase.auth().signInWithEmailAndPassword(email, pwd)
.then(function(firebaseUser) {
console.log('인증 성공')
// Todo add logic
})
.catch(function(error) {
console.log('인증 실패 : ', error);
});

이로써 저희는 로그인 기능을 구현할 수 있게 되었습니다.

Database(데이터베이스)

1) 실시간데이터베이스 : Firebase의 기존 데이터베이스로서, 여러 클라이언트에서 실시간으로 상태를 동기화해야 하는 모바일 앱을 위한 효율적이고 지연 시간이 짧은 솔루션입니다.
오프라인에도 실시간 데이터 통신을 하면서 최신상태 유지, api까지 지원해줌, 잠금모드와 테스트 모드가 있는데, 개발할때는 누구나 읽고, 쓸수있도록 테스트 모드로 하는 것을 추천합니다.
기본적으로 json형식으로 지원해줍니다.

  • 데이터를 하나의 큰 JSON 트리로 저장합니다.
    – 단순한 데이터를 매우 쉽게 저장합니다.
    – 복잡한 계층적 데이터를 대규모로 정리하기 어렵습니다.

2) Cloud Firestore :

  • 데이터를 문서 컬렉션으로 저장합니다.
    – 단순한 데이터를 JSON과 매우 비슷한 방식으로 문서에 쉽게 저장합니다.
    – 문서 안의 하위 컬렉션을 사용하여 복잡한 계층적 데이터를 대규모로 쉽게 정리할 수 있습니다.
    – 비정규화 및 데이터 평면화가 덜 필요합니다.

이외의 차이점은 https://firebase.google.com/docs/firestore/rtdb-vs-firestore?hl=ko 에서 확인 하실 수 있습니다.

firestore는 실시간 데이터베이스보다 풍부하고 빠른 쿼리와 우수한 확장성을 제공한다고 나와있지만 필자는 JSON 형식으로 지원해주는 RealTime 데이터베이스를 사용하려고 합니다.
처음 Database 화면에 접속하면 데이터베이스 만들기 버튼 바로 보이는데 이는 FireStore 데이터베이스이고 아래쪽에 RealTime 데이터베이스가 존재합니다.

firebase

데이터베이스를 만들때 규칙을 설정하게되는데 불러와야하기 때문에 테스트모드로 설정을 해줍니다. (규칙은 바꿀수 있음)

firebase
데이터베이스의 값입력을하면 위와같은 구조로 나타나게되고 JSON구조이기 때문에 접근하기 쉬울것이라 생각됩니다.
(필자는 아무렇지않게 firestore를 사용해놓고 호출은 RealTime database를 호출하여 헤멘적이있는데 다른 분들은 안그러실거라 믿습니다 ㅇㅅㅇ;)

이제 위에서 입력한 값을 코드에서 가져와서 사용해보겠습니다.
데이터 베이스의 값을 읽고 변경사항에 대해 수신 대기하려면 firebase.atabase.Reference의 on() 또는 once() 메소드를 사용하여 이벤트를 관찰합니다.

1
2
3
4
5
6
7
8
9
10
const ref = firebase.database().ref('/'); // ref('database경로'); / 가 최상위 루
ref.once('value').then(res => {
console.log('res : ', res)
});

//or

ref.on('value', snapshot => {
console.log('snapshot : ', snapshot)
});

쓰기와 업데이트 또는 삭제관련해서는 https://firebase.google.com/docs/database/web/read-and-write?hl=ko#get_a_database_reference를 참고하시면 됩니다.

Storage(저장소)

firebase Storage
문서, 사진, 파일, 동영상등 각종 파일을 저장하는 곳 이라고 생각하면 됩니다.
개발자들이 쉽게 파일들을 업로드하고 다운로드 할 수 있도록 해줍니다.

데이터베이스와 마찬가지로 규칙을 설정해주고 Storage의 위치를 지정해줍니다.
그 후 Storage 화면에서 파일을 업로드 할 수 있습니다.
firebase

firebase.storage().ref().child(‘root’).getDownloadURL()를 사용하여 업로드 한 이미지의 주소를 받아올 수 있습니다.

1
2
3
4
const storage = firebase.storage().ref();
storage.child('test_img.png').getDownloadURL().then(res => {
console.log('res : ', res);
})

추가로 파일의 업로드와 삭제에 대한 정보는
업로드
https://firebase.google.com/docs/storage/web/upload-files#manage_uploads
삭제
https://firebase.google.com/docs/storage/web/delete-files?hl=ko
에서 확인하시면 됩니다.

이번 글에서는 firebase에 대해 간단하게 알아보았고, 현재 개인적으로 firebase를 적용하고있는 Toy Project를 진행하면서 아직 사용해보지 않은 db와 storage 쪽의 업로드 및 삭제 혹은 firebase의 추가적으로 다른 기능들까지 사용해보고 글을 쓰게 될 것 같습니다.

{
  'level': 'master',
  'name': '김대원',
  'alias': '원바',
  'age': 32,
  'avility': {
    '수비': 1.4,
    '피지컬': 0.4,
    '스피드': 0.9,
    '창조력': 1.1,
    '공격': 1,
    '기술': 1,
    '제공권': 0.2,
    '정신': 0.5
  },
  'img': 'https://firebasestorage.googleapis.com/v0/b/fsa-project-60f97.appspot.com/o/wonba_slice.jpg?alt=media&token=b2c0292b-7238-4ee3-8222-0a687f6aa6c8',
  'intro': '하고싶은 말 - 원래 바보',
  'contact': '010-0000-0000'
},
{
  level: 'member',
  name: '김태양',
  alias: '매탱',
  age: '32',
  avility: {
    수비: 1.24,
    피지컬: 2.11,
    스피드: 0.11,
    창조력: 0.31,
    공격: 1.03,
    기술: 0.44,
    제공권: 0.33,
    정신: 0.72
  },
  img: 'https://firebasestorage.googleapis.com/v0/b/fsa-project-60f97.appspot.com/o/taeng_slice.jpg?alt=media&token=eeba83dc-26a5-453a-b5b9-639d33f9f01f',
  intro: '하고싶은말 - 탱탱한 매탱',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '박원일',
  alias: '박양',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'https://firebasestorage.googleapis.com/v0/b/fsa-project-60f97.appspot.com/o/parkyang.jpeg?alt=media&token=3e54dc99-0397-4315-84b3-775dff2800db',
  intro: '하고싶은말 - 야이 C XXXXXX',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '권세완',
  alias: '권세',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'https://firebasestorage.googleapis.com/v0/b/fsa-project-60f97.appspot.com/o/gwonse.jpeg?alt=media&token=df4ab5ee-048d-40ae-ae80-d26baa861a1c',
  intro: '하고싶은말 - 지렸당',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '심현수',
  alias: '면수',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '이지훈',
  alias: '이지',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '황지훈',
  alias: '황',
  age: '31',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '이유공',
  alias: '유공',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '김성진',
  alias: '성진',
  age: '27',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '권우재',
  alias: '우재',
  age: '27',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '이은기',
  alias: '은기',
  age: '27',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '이준규',
  alias: '흰둥이',
  age: '31',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '박석현',
  alias: '석현이형',
  age: '37',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '황민구',
  alias: '민구형님',
  age: '38',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '윤지혁',
  alias: '윤지혁',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '조한용',
  alias: '한용이',
  age: '26?',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '장성환',
  alias: '장성환',
  age: '32',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
},
{
  level: 'member',
  name: '김태주',
  alias: '태주',
  age: '24',
  avility: {
    수비: 0,
    피지컬: 0,
    스피드: 0,
    창조력: 0,
    공격: 0,
    기술: 0,
    제공권: 0,
    정신: 0
  },
  img: 'src/assets/images/empty.png',
  intro: '하고싶은말',
  contact: '010-0000-0000'
}

{
“0”: {
“author”: “gracehop”,
“title”: “Announcing COBOL, a New Programming Language”
“name”: “김대원”,
“alias”: “원바”,
“age”: 32,
“avility”: {
“수비”: 1.4,
“피지컬”: 0.4,
“스피드”: 0.9,
“창조력”: 1.1,
“공격”: 1,
“기술”: 1,
“제공권”: 0.2,
“정신”: 0.5
},
“img”: “https://firebasestorage.googleapis.com/v0/b/fsa-project-60f97.appspot.com/o/wonba_slice.jpg?alt=media&token=b2c0292b-7238-4ee3-8222-0a687f6aa6c8",
“intro”: “하고싶은 말 - 원래 바보”,
“contact”: “010-0000-0000”
},
“1”: {
“author”: “alanisawesome”,
“title”: “The Turing Machine”
}
}


Comments: