크레도스 2018. 1. 24. 16:09

Angular2Firebase 를 사용한 간단한 CRUD


Inflearn을 통해서 Firebase기본 강좌를 듣고 제가 주로 사용하고 있는 angular2와 함께 붙여서 간단한 CRUD를 만들어 봤습니다. 참고 사이느는 angular2firebase git site를 참고하였습니다. 내가 할 일에 대해 A,B,C 타입으로 나눠서 메모를 등록하는 Priority memo CRUD입니다.


    • 기본 개발 환경 설정

    • Auth

    • CRUD(Create, Read, Update, Delete) source 코딩

    • build & deploy


기본 개발환경 설정

개발환경 설정은 Angular-cli + angular2firebase를 사용하였습니다. angular-cli가 설치는 angular-cli site 참고하여 설치합니다. 아래 명령어를 통해 환경 세팅을 해줍니다. 

1
2
3
$ ng new angular-firebase-memo
 
$ npm install angularfire2 firebase --save
cs


위 명령어를 실행하면 project node_modules폴더에 angularfire2와 firebase가 설치됩니다.

개발 환경 셋팅을 마무리 하고 나면 firebase 사이트 콘솔로 이동하여 config 정보를 가져와야 합니다.

console에서 프로젝트 세팅을 완료한 뒤 위 그림처럼 웹 앱에 firebase 추가를 클릭하면 config정보들이 나옵니다. config정보를 이용하여 angular2에서 설정을 해줄 것 입니다. 만들어진 프로젝트에서 root/src/app/ 디렉토리에  firebase.app.config.ts 파일을 만들어 줍니다.


root/src/app/firebase.app.config.ts


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { AuthProviders, AuthMethods } from 'angularfire2/auth';
 
 
export const FirebaseAppConfig = {
    apiKey: "...",
    authDomain: "....firebaseapp.com",
    databaseURL: "https://....firebaseio.com",
    storageBucket: "....appspot.com",
    messagingSenderId: "xxxxxxxxx"
}
 
export const myFirebaseAppAuthConfig = {
  provider: AuthProviders.Google,
  method: AuthMethods.Redirect
};
 
cs


2개의 Object를 export하고 있습니다. FirebaseAppConfig는 설정 정보를 보여주고  myFirebaseAppAuthConfig 객체는 추후 로그인 인증을 위해 필요한 정보입니다. 일단은 Google에 현재페이지 redirect하는 방식으로 설정 해줍니다. 이제 이 객체들을 angular root module에 등록해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ... omitted ... 
// firebase config
import { FirebaseAppConfig, myFirebaseAppAuthConfig } from './firebase.app.config';
 
// ... omitted ...
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    //    ...omitted...
    AngularFireModule.initializeApp(FirebaseAppConfig,myFirebaseAppAuthConfig),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
cs


위 AppModule에서 import 배열안에 firebaseModule을 초기화 시켜주도록 소스를 작성합니다. 이제 기본 세팅은 마무리가 되었습니다.


Auth

firebase Api를 사용한다면 인증은 매우 쉽게 구현됩니다. 기본 google로그인 방식의 인증을 사용할 것 입니다. firebase console로 이동하여 아래 그림에서 클릭하는 순서대로 클릭을 해서 google 인증 방식을 사용한다고 설정합니다.



설정을 마친 뒤 Source를 작성하면 됩니다. 

root/src/app/app.component.html

1
2
3
4
<div class="main-container">
    <button class="btn btn-success" (click)="login()"> login with google </button>
    <button class="btn btn-warning" (click)="logout()"> logout </button>
</div>
cs


root/src/app/app.component.ts 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { Component, OnInit } from '@angular/core';
import { AngularFire } from 'angularfire2';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
    isLogin: boolean = false;
    constructor(
        private af: AngularFire
    ) {
        af.auth.subscribe(auth => {
            console.log(auth);
            if (auth.uid !== undefined){
                this.isLogin = true;
            }
            else {
                this.login();
            }
        });
    }
    ngOnInit(){
    }
    login(): void {
        this.af.auth.login();
    }
    logout(): void {
        this.af.auth.logout();
        this.isLogin = false;
    }
}
 
cs


버튼을 만들어주고 그에 해당하는 event를 component class안에서 작성합니다. contructor에서 AngularFire생성자를 주입받고 해당 생성자를 통해서 constructor구현부에 바로 subscribe 소스를 작성합니다. 해당 subscribe는 observable객체로 login후에 액션결과를 subscribe하고 잇는 부분으로 push되어 들어오게 됩니다. uid가 있다면 login상태를 true로 없다면 다시 login을 하도록 login method를 호출해줍니다. 위 2 페이지의 소스를 작성하면 login을 완료할 수 있습니다. 이제 로그인 이후의 로직인 CRUD를 작성하면 됩니다.


CRUD(Create, Read, Update, Delete) source 코딩

저는 폴더 구조를 다음과 같이 만들었습니다.


pages를 만들어 루트 폴더하위에 들어가게 될 페이지들의 컴퍼넌트를 만들고 page하위 컴퍼넌트들을 page.module.ts 관리할 수 있도록 만들어 주었습니다. angular에서 component단위의 개발이 가능해지면서 컴퍼넌트 트리를 만들어주고 컴퍼넌트 트리들은 또 모듈로 묶어주어 모듈별 관리를 가능하게 할 수 있습니다. 더 세분화 하여 구조를 가져갈 수도 있으나 이 프로젝트에서는 많은 컴퍼넌트가필요하지 않아 pages.module.ts 하나만 만들어 root Module에 import해줄 것 입니다. new-memo page에서는 Create를 하고, show-memo에서는 Delete, Update, Read를 하게 됩니다. 아래와 같은 구조 입니다.



root/src/app/pages/new-memo/new-memo.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { Component, OnInit } from '@angular/core';
import {AngularFire, FirebaseListObservable} from 'angularfire2';
 
@Component({
    selector: 'new-memo',
    templateUrl: 'new-memo.component.html',
    styleUrls: ['new-memo.component.css']
})
export class NewMemoComponent implements OnInit {
 
    //...
    constructor(
        private af: AngularFire
    ) { 
        //...
        af.auth.subscribe(auth => {
            this.user_uid = auth.uid;
        });
    }
    ngOnInit() { }
 
    insertNewMemo() {
        //...
        const memoObservable = this.af.database.list('/pmemos/'+this.user_uid);
        memoObservable.push(memo_obj);
        //...
    }
}
cs


중점적으로 봐야할 부분은 insertNewMemo 함수입니다. af.database.list('/[name]/' + uid); pmemos는 firebase database에서 만들고자 하는 컬렉션 json이름입니다. firebase는 컬렉션들을 url 형식으로 가져오는 방식을 사용하고 있습니다. new-memo 컴퍼넌트에서도 역시 auth.subscribe를 통해서 uid를 저장해주고 있는대 이부분은 메모를 가져올때 로그인한 user것만 가져오도록 합니다. 모든 list를 가져와서 해당 리스트에 새로만들어질 memo를 push해주는 방식으로 새로운 메모를 Create할 수 있습니다.


이번엔 update와 delete, Read입니다. 방식은 거의 비슷하므로 간단한 설명은 주석으로하겟습니다.



root/src/app/pages/show-memo/show-memo.component.ts


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { Observable } from '@angular-cli/ast-tools/node_modules/rxjs/Rx';
import { Component, ElementRef, OnInit } from '@angular/core';
import {AngularFire, FirebaseListObservable} from 'angularfire2';
 
@Component({
    selector: 'show-memo',
    templateUrl: 'show-memo.component.html',
    styleUrls: ['show-memo.component.css']
})
export class ShowMemoComponent implements OnInit {
    // memo에서 list를 받아저장하는 observable객체
    pmemos$: FirebaseListObservable<any[]>;
    // array에 data를 담아서 angular ngFor를 사용하여 iteratorable하게 만들어 준다.
    pmemos: Array<any> = [];
    constructor(
        private af: AngularFire
    ) { 
        // uid를 변수에 저장.
        af.auth.subscribe(auth => {
            this.user_uid = auth.uid;
        });
    }
    ngOnInit() { 
        this._setPriorityMemoList();
    }
    private _setPriorityMemoList(): void {
 
        // list를 모두 가져와서 pmemo에 data하나씩 너어주는 소스
        this.pmemos$ = this.af.database.list('/pmemos/' + this.user_uid);
        this.pmemos$.subscribe(data => {
            this.pmemos = data;
        })
    }
    delete(key: string): void {
        // pmemos$ observable객체를 이용하여 remove. remove시에는 해당 memo에대한 key를 받아와야 한다.
        // memo.$key에 키값이 있다.
        this.pmemos$.remove(key);
    }
 
    edit(oMemo: any, key: string): void {
        this.selectedMemo = oMemo;
        // edit버튼 클릭시 memoKey를 변수에 저장
        this.memoKey = key;
    }
    updateMemo(): void {
        // update를 위해 delete처럼 키값 그리고 2번째 파라미터에는 바뀐 내용을 담은 object
        this.pmemos$.update(this.memoKey, memo_obj);
        this.cancelUpdate();
    }
}
cs



Build & Deploy

위 소스를 통해서 웹 페이지에서 잘 보이도록 만들어 준뒤 build를 하고 deploy를 해야 합니다. 다음 명령어를 실행해서 production 환경으로 빌드해줍니다.

1
$ ng build --prod
cs

빌드가 끝나면 dist 폴더 하위에 소스들이 모두 빌드되어 들어가게 됩니다. terminal을 이용하여 해당 dist 폴더로 들어가서 deploy해줄 것 입니다. deploy명령어는 다음 순서대로 하면 됩니다.

1
2
3
4
5
$ firebase login
 
$ firebase init
 
$ firebase deploy
cs


firebase login을 통해서 로그인을 한번 해줘야 합니다. 로그인 후 firebase init 단계에서는 몇가지 선택을 해줘야 하는대, public 이란 단어가 나오면 현재 디렉토리를 뜻하는 . 을 입력하고 Enter를, spa 란단어가 나오면 Y, Override란 단어가 나오면 N 순으로 입력해주면 됩니다. firebase는 init할때 public폴더와 index.html페이지를 만들어 주는데 이미 angular 빌드를 통해서 만들었기 때문에 모두 넘어가면 됩니다. 



git : https://github.com/arnoldyoo/angular-pmemo

memo site : https://angular-firebase-memo.firebaseapp.com/



출처: http://arnoldyoo.tistory.com/16 [Arnold's life]