Google은 흑인 공동체를 위한 인종적 평등을 추구하기 위해 노력하고 있습니다. 자세히 알아보기
이 페이지는 Cloud Translation API를 통해 번역되었습니다.
Switch to English

웹용 Firebase 알아보기

이 코드 랩에서는 대화 형 웹 애플리케이션을 만들기위한 Firebase의 몇 가지 기본 사항을 배웁니다. 여러 Firebase 제품을 사용하여 이벤트 RSVP 및 방명록 채팅 앱을 빌드하고 배포합니다.

59abdefbcc23bbbe.png

배울 것

  • Firebase 인증 및 FirebaseUI로 사용자를 인증합니다.
  • Cloud Firestore를 사용하여 데이터를 동기화합니다.
  • Firebase 보안 규칙을 작성하여 데이터베이스를 보호하세요.
  • Firebase 호스팅에 웹 앱을 배포합니다.

필요한 것

  • Chrome과 같은 원하는 브라우저.
  • stackblitz.com에 대한 액세스 (계정 또는 로그인 필요 없음).
  • Gmail 계정과 같은 Google 계정. GitHub 계정에 이미 사용하고있는 이메일 계정을 권장합니다. 이를 통해 StackBlitz의 고급 기능을 사용할 수 있습니다.
  • 코드 랩의 샘플 코드입니다. 코드를 얻는 방법은 다음 단계를 참조하십시오.

이 Codelab에서는 여러 Firebase 워크 플로가 통합 된 온라인 편집기 인 StackBlitz를 사용하여 앱을 빌드하고 배포합니다. Stackblitz는 소프트웨어 설치 나 특별한 StackBlitz 계정이 필요하지 않습니다.

StackBlitz를 사용하면 다른 사람과 프로젝트를 공유 할 수 있습니다. StackBlitz 프로젝트 URL이있는 다른 사람은 코드를보고 프로젝트를 포크 할 수 있지만 StackBlitz 프로젝트를 편집 할 수는 없습니다.

  1. 시작 코드는 다음 URL로 이동 하십시오. ** https : //stackblitz.com/edit/firebase-gtk-web-** start
  2. StackBlitz 페이지 상단에서 Fork를 클릭합니다. f5135360aef481cc.png

이제 자체 StackBlitz 프로젝트로 시작 코드의 복사본이 있습니다. 로그인하지 않았으므로 계정 이름은 @anonymous 이지만 프로젝트에는 고유 URL과 함께 고유 한 이름이 있습니다. 모든 파일과 변경 사항은이 StackBlitz 프로젝트에 저장됩니다.

이 코드 랩의 시작 자료는 일부 스타일 시트 및 앱용 HTML 컨테이너 몇 개를 포함하여 웹 앱에 대한 일부 구조를 제공합니다. 이 코드 랩의 뒷부분에서 이러한 컨테이너를 Firebase에 연결합니다.

시작하려면 StackBlitz 인터페이스에 대해 좀 더 익숙해 지겠습니다.

  1. StackBlitz에서 index.html 파일을 엽니 다.
  2. event-details-containerdescription-container 찾은 다음 일부 이벤트 세부 정보를 수정 해보세요.

텍스트를 편집 할 때 StackBlitz의 자동 페이지 다시로드에 새 이벤트 세부 정보가 표시됩니다. 멋지죠?

<!-- ... -->

<div id="app">
  <img src="..." />

  <section id="event-details-container">
     <h1>Firebase Meetup</h1>

     <p><i class="material-icons">calendar_today</i> October 30</p>
     <p><i class="material-icons">location_city</i> San Francisco</p>

  </section>

  <hr>

  <section id="firebaseui-auth-container"></section>

  <section id="description-container">
     <h2>What we'll be doing</h2>
     <p>Join us for a day full of Firebase Workshops and Pizza!</p>
  </section>
</div>



<!-- ... -->

앱 미리보기는 다음과 같아야합니다.

앱 미리보기

908cc57ce3a5b5fe.png

이벤트 정보를 표시하는 것은 게스트에게 좋지만 이벤트를 표시하는 것만으로는 누구에게나 유용하지 않습니다. 이 앱에 몇 가지 동적 기능을 추가해 보겠습니다. 이를 위해서는 Firebase를 앱에 연결해야합니다. Firebase를 시작하려면 Firebase 프로젝트를 만들고 설정해야합니다.

Firebase 프로젝트 만들기

  1. Firebase에 로그인합니다.
  2. Firebase 콘솔에서 프로젝트 추가 (또는 프로젝트 만들기 )를 클릭하고 Firebase 프로젝트 이름을 Firebase-Web-Codelab으로 지정 합니다.

a67c239f8cc7f4b5.png

  1. 프로젝트 생성 옵션을 클릭하십시오. 메시지가 표시되면 Firebase 약관에 동의합니다. 이 앱에 Analytics를 사용하지 않을 것이므로 Google Analytics 설정을 건너 뛰십시오.

Firebase 프로젝트에 대한 자세한 내용은 Firebase 프로젝트 이해를 참조하세요.

빌드중인 앱은 웹 앱에 사용할 수있는 여러 Firebase 제품을 사용합니다.

  • Firebase 인증Firebase UI 를 통해 사용자가 앱에 쉽게 로그인 할 수 있습니다.
  • Cloud Firestore 는 구조화 된 데이터를 클라우드에 저장하고 데이터가 변경 될 때 즉시 알림을받습니다.
  • 데이터베이스 보안을위한 Firebase 보안 규칙 .
  • 자산을 호스팅하고 제공하기위한 Firebase 호스팅 .

이러한 제품 중 일부는 특별한 구성이 필요하거나 Firebase 콘솔을 사용하여 사용 설정해야합니다.

Firebase 인증위한 이메일 로그인 사용

사용자가 웹 앱에 로그인 할 수 있도록하려면이 코드 랩에 이메일 / 비밀번호 로그인 방법을 사용합니다.

  1. Firebase 콘솔의 왼쪽 패널에서 개발 을 클릭합니다.
  2. 인증을 클릭 한 다음 로그인 방법 탭을 클릭합니다 (또는 여기를 클릭하여 로그인-의 방법 탭으로 바로 이동합니다).
  3. 로그인 공급자 목록에서 이메일 / 비밀번호 를 클릭하고 사용 스위치를 켜기 위치로 설정 한 다음 저장 을 클릭합니다. 4c88427cfd869bee.png

Cloud Firestore 사용

웹 앱은 Cloud Firestore 를 사용하여 채팅 메시지를 저장하고 새 채팅 메시지를받습니다.

Cloud Firestore를 사용 설정합니다.

  1. Firebase 콘솔의 개발 섹션에서 데이터베이스를 클릭합니다.
  2. Cloud Firestore 에서 데이터베이스 만들기를 클릭 합니다 . 3ce19fd6467e51c5.png
  1. 테스트 모드 에서 시작 옵션을 선택합니다. 보안 규칙에 대한 고지 사항을 읽으십시오. 테스트 모드를 사용하면 개발 중에 데이터베이스에 자유롭게 쓸 수 있습니다. 다음을 클릭합니다. 56369cebb9300eb.png
  1. 데이터베이스 위치를 선택하십시오 (기본값 만 사용할 수 있음). 이 위치는 나중에 변경할 수 없습니다. 32f815f4648c3174.png
  2. 완료를 클릭합니다.

이제 Firebase 프로젝트를 만들고 일부 서비스를 사용 설정 했으므로 Firebase를 사용할 코드와 사용할 Firebase 프로젝트를 알려야합니다.

Firebase 라이브러리 추가

앱에서 Firebase를 사용하려면 앱에 Firebase 라이브러리를 추가해야합니다. Firebase 문서에 설명 된 대로이를 수행하는 방법에는 여러 가지가 있습니다 . 예를 들어 Google의 CDN에서 라이브러리를 추가하거나 npm을 사용하여 로컬에 설치 한 다음 Browserify를 사용하는 경우 앱에서 패키지화 할 수 있습니다.

StackBlitz는 자동 번들링을 제공하므로 import 문을 사용하여 Firebase 라이브러리를 추가 할 수 있습니다.

이 앱을 빌드하려면 Firebase 인증, FirebaseUI, Cloud Firestore 라이브러리를 사용합니다. 이 코드 랩의 경우 index.js 파일 상단에 다음 줄이 이미 포함되어 있습니다.

// Import stylesheets
import "./style.css";

// Firebase App (the core Firebase SDK) is always required
// and must be listed first
import * as firebase from "firebase/app";

// Add the Firebase products that you want to use
import "firebase/auth";
import "firebase/firestore";

import * as firebaseui from "firebaseui";

프로젝트에 Firebase 웹 앱 추가

  1. Firebase 콘솔로 돌아가서 왼쪽 상단의 프로젝트 개요 를 클릭하여 프로젝트의 개요 페이지로 이동합니다.
  2. 프로젝트 개요 페이지 중앙에서 웹 아이콘을 클릭합니다. b286f3d215e1f578.png 새 Firebase 웹 앱을 만듭니다. c167e9526fad2825.png
  3. Web App 이라는 닉네임으로 앱을 등록합니다.
  4. 이 Codelab의 경우이 앱에 대해 Firebase 호스팅도 설정 옆의 체크 박스를 선택 하지 마세요 . 지금은 StackBlitz의 미리보기 창을 사용합니다.
  5. 앱 등록을 클릭 합니다 . c85ac8aa351e2560.png
  6. Firebase 구성 개체 를 클립 보드에 복사합니다. ed1e598c6132f734.png
  7. 콘솔 계속을 클릭합니다.

앱에 Firebase 구성 개체를 추가합니다.

  1. StackBlitz로 돌아가 index.js 파일로 이동합니다.
  2. Add Firebase project configuration object here 주석 줄을 찾아 주석 바로 아래에 구성 스 니펫을 붙여 넣습니다.
  3. 고유 한 Firebase 프로젝트 구성을 사용하여 Firebase를 설정하려면 initializeApp 함수 호출을 추가합니다.
// ...

// Add Firebase project configuration object here
var firebaseConfig = {
  apiKey: "random-unique-string",
  authDomain: "your-projectId.firebaseapp.com",
  databaseURL: "https://your-projectId.firebaseio.com",
  projectId: "your-projectId",
  storageBucket: "your-projectId.appspot.com",
  messagingSenderId: "random-unique-string",
  appId: "random-unique-string",
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

이제 앱에 Firebase를 추가 했으므로 Firebase 인증을 사용하여 사용자를 등록하는 RSVP 버튼을 설정할 수 있습니다.

이메일 로그인 및 FirebaseUI로 사용자 인증

사용자에게 이메일 주소로 로그인하라는 메시지를 표시하는 RSVP 버튼이 필요합니다. FirebaseUI 를 RSVP 버튼에 연결하여이 작업을 수행 할 수 있습니다 .FirebaseUI는 Firebase Auth 위에 미리 빌드 된 UI를 제공하는 라이브러리입니다.

FirebaseUI에는 다음 두 가지 작업을 수행하는 구성 ( 문서 의 옵션 참조)이 필요합니다.

  1. 이메일 / 비밀번호 로그인 방법을 사용하겠다고 FirebaseUI에 알립니다.
  2. 성공적인 로그인에 대한 콜백을 처리하고 리디렉션을 방지하기 위해 false를 반환합니다. 단일 페이지 웹 앱을 빌드하고 있기 때문에 페이지를 새로 고치지 않으려 고합니다.

먼저 FirebaseUI를 초기화하는 코드를 추가합니다.

  1. StackBlitz에서 index.js 파일로 이동합니다. FirebaseUI 구성이 이미 제공되어 있습니다.
  2. index.js, 하단에 다음과 같이 FirebaseUI 초기화 문을 추가합니다.
// ...
// Initialize the FirebaseUI widget using Firebase
const ui = new firebaseui.auth.AuthUI(firebase.auth());

다음으로 HTML에 RSVP 버튼을 추가합니다.

  1. StackBlitz에서 index.html 파일로 이동합니다.
  2. 아래 예와 같이 event-details-container 내부에 RSVP 버튼 용 HTML을 추가합니다.

이 코드 랩의 경우 index.js 파일에 이러한 특정 ID에 대한 후크가 이미 있으므로 아래와 같이 동일한 id 값을 사용하도록주의하십시오.

index.html 파일에는 ID가 firebaseui-auth-container 있습니다. 로그인을 유지하기 위해 FirebaseUI에 전달할 ID입니다.

<!-- ... -->

<section id="event-details-container">
    <!-- ... -->
    <!-- ADD THE RSVP BUTTON HERE -->
    <button id="startRsvp">RSVP</button>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<!-- ... -->

앱 미리보기

ab9ad7d61bb7b28c.png

  1. RSVP 버튼에 리스너를 설정하고 FirebaseUI 시작 함수를 호출합니다. 로그인 창을보고 싶다고 FirebaseUI에 알립니다. index.js 하단에 다음 코드를 추가합니다.
// ... 
// At the bottom

// Listen to RSVP button clicks
startRsvpButton.addEventListener("click",
 () => {
      ui.start("#firebaseui-auth-container", uiConfig);
});

앱 로그인 테스트

  1. StackBlitz의 미리보기 창에서 RSVP 버튼을 클릭하여 앱에 로그인합니다.
  • 이 코드 랩의 경우이 코드 랩에 대한 이메일 확인 단계를 설정하지 않기 때문에 모든 이메일 주소 (가짜 이메일 주소 포함)를 사용할 수 있습니다.
  • auth/operation-not-allowed 또는 The given sign-in provider is disabled for this Firebase project 라는 오류 메시지가 표시되면 Firebase 콘솔에서 로그인 제공 업체로 이메일 / 비밀번호 를 사용 설정했는지 확인하세요.
  1. Firebase 콘솔의 인증 대시 보드 로 이동합니다. 사용자 탭에서 앱에 로그인하기 위해 입력 한 계정 정보를 볼 수 있습니다.

앱 미리보기

3024f90b52ad55fe.png

682fc0eca86a99fc.png

UI에 인증 상태 추가

이제 UI가 로그인 사실을 반영하는지 확인합니다.

사용자의 로그인 상태가 변경 될 때마다 알림을받는 Firebase 인증 상태 리스너 콜백을 사용합니다. 현재 사용자가있는 경우 RSVP 버튼을 로그 아웃 버튼으로 전환합니다.

  1. StackBlitz에서 index.js 파일로 이동합니다.
  2. 하단에 다음 코드를 추가합니다.
// ...
// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user)=> {
  if (user) {
    startRsvpButton.textContent = "LOGOUT"
  }
  else {
    startRsvpButton.textContent = "RSVP"
  }
});
  1. 버튼 리스너에서 현재 사용자가 있는지 확인하고 로그 아웃합니다. 이렇게하려면 현재 startRsvpButton.addEventListener 를 다음으로 startRsvpButton.addEventListener .
// ...
// Called when the user clicks the RSVP button
startRsvpButton.addEventListener("click",
 () => {
    if (firebase.auth().currentUser) {
      // User is signed in; allows user to sign out
      firebase.auth().signOut();
    } else {
      // No user is signed in; allows user to sign in
      ui.start("#firebaseui-auth-container", uiConfig);
    }
});

이제 버튼에 LOGOUT 이 표시되고 클릭하면 RSVP 로 다시 전환됩니다.

앱 미리보기

4c540450924f1607.png

사용자가 오는 것을 아는 것은 좋지만 게스트에게 앱에서 할 수있는 다른 작업을 제공합시다. 방명록에 메시지를 남길 수 있다면 어떨까요? 그들은 왜 그들이 오기를 기대하는지 또는 만나기를 희망하는 사람을 공유 할 수 있습니다.

사용자가 앱에 작성한 채팅 메시지를 저장하려면 Cloud Firestore를 사용합니다.

데이터 모델

Cloud Firestore는 NoSQL 데이터베이스이며 데이터베이스에 저장된 데이터는 컬렉션, 문서, 필드, 하위 컬렉션으로 분할됩니다. 채팅의 각 메시지는 guestbook 이라는 최상위 컬렉션에 문서로 저장됩니다.

b447950f9f993789.png

Firestore에 메시지 추가

이 섹션에서는 사용자가 데이터베이스에 새 메시지를 작성하는 기능을 추가합니다. 먼저 UI 요소 (메시지 필드 및 보내기 버튼)에 대한 HTML을 추가 한 다음 이러한 요소를 데이터베이스에 연결하는 코드를 추가합니다.

메시지 필드 및 보내기 버튼의 UI 요소를 추가하려면 다음을 수행하십시오.

  1. StackBlitz에서 index.html 파일로 이동합니다.
  2. guestbook-container 를 찾고 다음 HTML을 추가하여 메시지 입력 필드와 보내기 버튼이있는 양식을 만듭니다.
<!-- ... -->

 <section id="guestbook-container">
   <h2>Discussion</h2>

   <form id="leave-message">
     <label>Leave a message: </label>
     <input type="text" id="message">
     <button type="submit">
       <i class="material-icons">send</i>
       <span>SEND</span>
     </button>
   </form>

 </section>

<!-- ... -->

앱 미리보기

4a892284443cf73d.png

사용자가 SEND 버튼을 클릭하면 아래 코드 스 니펫이 트리거됩니다. 데이터베이스의 guestbook 컬렉션에 메시지 입력 필드의 내용을 추가합니다. 특히 add 메서드는 guestbook 컬렉션에 새 문서 (자동 생성 된 ID 사용)에 메시지 콘텐츠를 추가합니다.

  1. StackBlitz에서 index.js 파일로 이동합니다.
  2. 파일 맨 아래에 다음 코드를 추가하십시오.

firebase.auth().currentUser.uid 는 Firebase 인증이 로그인 한 모든 사용자에게 제공하는 자동 생성 고유 ID에 대한 참조입니다.

// ..
// Listen to the form submission
form.addEventListener("submit", (e) => {
 // Prevent the default form redirect
 e.preventDefault();
 // Write a new message to the database collection "guestbook"
 firebase.firestore().collection("guestbook").add({
   text: input.value,
   timestamp: Date.now(),
   name: firebase.auth().currentUser.displayName,
   userId: firebase.auth().currentUser.uid
 })
 // clear message input field
 input.value = ""; 
 // Return false to avoid redirect
 return false;
});

로그인 한 사용자에게만 방명록 표시

누군가 가 게스트의 채팅을 보는 것을 원하지는 않습니다. 채팅 보안을 위해 할 수있는 한 가지 방법은 로그인 한 사용자 만 방명록을 볼 수 있도록 허용하는 것입니다. 즉, 자체 앱의 경우 Firebase 보안 규칙으로 데이터베이스를 보호하는 것이 좋습니다. (코드 랩의 뒷부분에 보안 규칙에 대한 자세한 정보가 있습니다.)

  1. StackBlitz에서 index.js 파일로 이동합니다.
  2. onAuthStateChanged 리스너를 편집하여 방명록을 숨기고 표시합니다.
// ...
// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user) => {
 if (user){
   startRsvpButton.textContent = "LOGOUT";
   // Show guestbook to logged-in users
   guestbookContainer.style.display = "block";
 }
 else{
   startRsvpButton.textContent = "RSVP";
   // Hide guestbook for non-logged-in users
   guestbookContainer.style.display = "none";
 }
});

메시지 보내기 테스트

  1. 앱에 로그인했는지 확인하세요.
  2. "Hey there!"와 같은 메시지를 입력 한 다음 SEND 를 클릭합니다.

이 작업은 Cloud Firestore 데이터베이스에 메시지를 작성합니다. 그러나 여전히 데이터 검색을 구현해야하므로 실제 웹 앱에는 아직 메시지가 표시되지 않습니다. 다음에 할 것입니다.

하지만 Firebase 콘솔에서 새로 추가 된 메시지를 볼 수 있습니다.

Firebase 콘솔의 데이터베이스 대시 보드 에 새로 추가 된 메시지와 함께 guestbook 컬렉션이 표시되어야합니다. 메시지를 계속 보내면 방명록 컬렉션에 다음과 같은 많은 문서가 포함됩니다.

Firebase 콘솔

713870af0b3b63c.png

메시지 동기화

게스트는 데이터베이스에 메시지를 쓸 수 있지만 아직 앱에서는 볼 수 없습니다.

메시지를 표시하려면 데이터가 변경 될 때 트리거하는 리스너를 추가 한 다음 새 메시지를 표시하는 UI 요소를 만들어야합니다.

앱에서 새로 추가 된 메시지를 수신하는 코드를 추가합니다. 먼저 HTML에 섹션을 추가하여 메시지를 표시합니다.

  1. StackBlitz에서 index.html 파일로 이동합니다.
  2. guestbook-container 에서 guestbook ID로 새 섹션을 추가합니다.
<!-- ... -->

  <section id="guestbook-container">
   <h2>Discussion</h2>

   <form><!-- ... --></form>

   <section id="guestbook"></section>

 </section>

<!-- ... -->

다음으로 데이터 변경 사항을 수신하는 리스너를 등록합니다.

  1. StackBlitz에서 index.js 파일로 이동합니다.
  2. 파일 맨 아래에 다음 코드를 추가하여 데이터베이스의 모든 문서 (방명록 메시지)를 반복합니다.
// ...
// Create query for messages
firebase.firestore().collection("guestbook")
.orderBy("timestamp","desc")
.onSnapshot((snaps) => {
 // Reset page
 guestbook.innerHTML = "";
 // Loop through documents in database
 snaps.forEach((doc) => {
   // Create an HTML entry for each document and add it to the chat
   const entry = document.createElement("p");
   entry.textContent = doc.data().name + ": " + doc.data().text;
   guestbook.appendChild(entry);
 });
});

데이터베이스의 메시지를 수신하려면 .collection 함수를 사용하여 특정 컬렉션에 대한 쿼리를 만듭니다. 위의 코드는 채팅 메시지가 저장되는 guestbook 컬렉션의 변경 사항을 수신합니다. 메시지는 .orderBy('timestamp', 'desc') 를 사용하여 날짜별로 정렬되어 최신 메시지를 맨 위에 표시합니다.

.onSnapshot 함수는 콜백 함수라는 하나의 매개 변수를 사용합니다. 콜백 함수는 쿼리와 일치하는 문서에 변경 사항이있을 때 트리거됩니다. 메시지가 삭제, 수정 또는 추가되는 경우 일 수 있습니다. 자세한 내용은 Cloud Firestore 문서를 참조하세요.

메시지 동기화 테스트

Cloud Firestore는 데이터베이스를 구독하는 클라이언트와 데이터를 자동으로 즉시 동기화합니다.

  1. 데이터베이스에서 이전에 만든 메시지가 앱에 표시되어야합니다. 새 메시지를 자유롭게 작성하십시오. 즉시 나타나야합니다.
  2. 여러 창 또는 탭에서 작업 영역을 열면 메시지가 여러 탭에서 실시간으로 동기화됩니다.
  3. (선택 사항) Firebase 콘솔의 데이터베이스 섹션에서 직접 새 메시지를 수동으로 삭제, 수정 또는 추가 할 수 있습니다. UI에 변경 사항이 표시되어야합니다.

축하합니다! 앱에서 Cloud Firestore 문서를 읽고 있습니다!

앱 P 검토

e30df0a9614bae7d.png

처음에는 테스트 모드를 사용하도록 Cloud Firestore를 설정했습니다. 즉, 데이터베이스가 읽기 및 쓰기를 위해 열려 있음을 의미합니다. 그러나 개발 초기 단계에서만 테스트 모드를 사용해야합니다. 모범 사례로 앱을 개발할 때 데이터베이스에 대한 보안 규칙을 설정해야합니다. 보안은 앱의 구조와 동작에 필수적이어야합니다.

보안 규칙을 사용하면 데이터베이스의 문서 및 컬렉션에 대한 액세스를 제어 할 수 있습니다. 유연한 규칙 구문을 사용하면 전체 데이터베이스에 대한 모든 쓰기에서 특정 문서에 대한 작업에 이르기까지 모든 항목과 일치하는 규칙을 만들 수 있습니다.

Firebase 콘솔에서 Cloud Firestore에 대한 보안 규칙을 작성할 수 있습니다.

  1. Firebase 콘솔의 개발 섹션에서 데이터베이스를 클릭 한 다음 규칙 탭을 선택합니다 (또는 여기클릭 하여 규칙 탭으로 바로 이동).
  2. 공개 된 규칙에 대한 경고와 함께 다음 기본 보안 규칙이 표시되어야합니다.

7767a2d2e64e7275.png

컬렉션 식별

먼저 앱이 데이터를 쓰는 컬렉션을 식별합니다.

match /databases/{database}/documents 에서 보호 할 컬렉션을 식별합니다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
     // You'll add rules here in the next step.
  }
}

보안 규칙 추가

각 방명록 문서에서 인증 UID를 필드로 사용했기 때문에 인증 UID를 가져 와서 문서에 쓰려는 모든 사람이 일치하는 인증 UID를 가지고 있는지 확인할 수 있습니다.

아래와 같이 규칙 세트에 읽기 및 쓰기 규칙을 추가합니다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow create:
        if request.auth.uid == request.resource.data.userId;
    }
  }
}

이제 방명록의 경우 로그인 한 사용자 만 메시지 (모든 메시지!)를 읽을 수 있지만 사용자 ID로만 메시지를 작성할 수 있습니다. 또한 메시지를 편집하거나 삭제할 수 없습니다.

유효성 검사 규칙 추가

데이터 유효성 검사를 추가하여 예상되는 모든 필드가 문서에 있는지 확인합니다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow create:
      if request.auth.uid == request.resource.data.userId
          && "name" in request.resource.data
          && "text" in request.resource.data
          && "timestamp" in request.resource.data;
    }
  }
}

리스너 재설정

이제 앱에서 인증 된 사용자 만 로그인 할 수 있으므로 인증 리스너 내에서 방명록 firestore 쿼리를 이동해야합니다. 그렇지 않으면 권한 오류가 발생하고 사용자가 로그 아웃 할 때 앱 연결이 끊어집니다.

  1. 방명록 컬렉션 onSnapshot 리스너를 subscribeGuestbook 이라는 새 함수로 onSnapshot . 또한 onSnapshot 함수의 결과를 guestbookListener 변수에 할당합니다.

Firestore onSnapshot 리스너 나중에 스냅 샷 리스너를 취소하는 데 사용할 수있는 구독 취소 함수를 반환 합니다.

// ...
// Listen to guestbook updates
function subscribeGuestbook(){
   // Create query for messages
 guestbookListener = firebase.firestore().collection("guestbook")
 .orderBy("timestamp","desc")
 .onSnapshot((snaps) => {
   // Reset page
   guestbook.innerHTML = "";
   // Loop through documents in database
   snaps.forEach((doc) => {
     // Create an HTML entry for each document and add it to the chat
     const entry = document.createElement("p");
     entry.textContent = doc.data().name + ": " + doc.data().text;
     guestbook.appendChild(entry);
   });
 });
};
  1. unsubscribeGuestbook 이라는 새 함수를 아래에 추가합니다. guestbookListener 변수가 null이 아닌지 guestbookListener 다음 함수를 호출하여 리스너를 취소합니다.
// ...
// Unsubscribe from guestbook updates
function unsubscribeGuestbook(){
 if (guestbookListener != null)
 {
   guestbookListener();
   guestbookListener = null;
 }
};
  1. 마지막으로 onAuthStateChanged 콜백에 새 함수를 추가합니다 (다음 두 단계 사용).
  2. if (user) 하단에 subscribeGuestbook() 을 추가합니다.
  3. else 문의 맨 아래에 unsubscribeGuestbook() 을 추가합니다.
// ...
firebase.auth().onAuthStateChanged((user) => {
if (user){
  startRsvpButton.textContent = "LOGOUT";
  // Show guestbook to logged-in users
  guestbookContainer.style.display = "block";

  // Subscribe to the guestbook collection
  subscribeGuestbook();
}
else{
  startRsvpButton.textContent = "RSVP";
  // Hide guestbook for non-logged-in users
  guestbookContainer.style.display = "none";

  // Unsubscribe from the guestbook collection
  unsubscribeGuestbook();
}
});

Firebase는 웹 앱의 자산을 제공하는 호스팅 서비스 를 제공합니다. Firebase 명령 줄 인터페이스 (CLI)를 사용하여 Firebase 호스팅에 파일 및 호스팅 구성을 배포 할 수 있습니다. 하지만이 코드 랩에서는 Firebase CLI를 작업 공간에 통합 한 StackBlitz를 사용 하고 있습니다!

StackBlitz의 Firebase 통합을 사용하여 StackBlitz에 애셋을 배포 할 Firebase 프로젝트를 알릴 수 있습니다.

  1. StackBlitz에서 GitHub로 아직 로그인하지 않은 경우 오른쪽 상단에서 로그인을 클릭 한 다음 GitHub 계정 자격 증명을 입력합니다.

99a41778bb3c194c.png

  • 이미 GitHub 계정이있는 경우 GitHub 계정을 사용하여 로그인합니다.
  • 아직 GitHub 계정이없는 경우 Firebase에 로그인 할 때 사용한 것과 동일한 이메일 주소를 사용하여 GitHub 계정을 만듭니다.
  1. 이제 왼쪽 패널에 Firebase 아이콘이 있습니다.

2981c2e3ad13c2c1.png 3. Google에 로그인을 클릭합니다. Firebase에 로그인 할 때 사용한 것과 동일한 이메일 주소를 사용하여 로그인합니다. 4. Firebase 프로젝트 목록에서 Firebase-Web-Codelab 프로젝트를 선택합니다.

StackBlitz를 사용하여 Firebase 호스팅에 배포하는 것은 말 그대로 원 클릭 작업입니다.

  1. StackBlitz 작업 영역에서 페이지 왼쪽에있는 배포 를 클릭합니다. 네, 그게 다입니다. 한 걸음! 8fe6c0bfc04c8935.png

Firebase 호스팅 작동 방식 에 대한 자세한 내용은 설명서를 참조하세요.

프로젝트의 Firebase 콘솔 호스팅 섹션으로 이동하여 배포 기록, 앱의 이전 버전으로 롤백하는 기능, 커스텀 도메인을 설정하는 워크 플로 등 유용한 호스팅 정보와 도구를 확인하세요.

참석자의 회신 상태 기록

지금은 앱에서 사람들이 이벤트에 관심이있는 경우 채팅을 시작할 수 있습니다. 또한 누군가가 오는지 아는 유일한 방법은 채팅에 게시하는 것입니다. 정리하고 사람들에게 얼마나 많은 사람들이 오는지 알려주세요.

이벤트에 참석하고 싶은 사람을 등록하는 토글을 추가 한 다음, 오는 사람의 수를 수집합니다.

  1. StackBlitz에서 index.html 파일로 이동합니다.
  2. guestbook-container 에서 다음과 같이 YESNO 버튼 집합을 추가합니다.
<!-- ... -->
  <section id="guestbook-container">
   <h2>Are you attending?</h2>
     <button id="rsvp-yes">YES</button>
     <button id="rsvp-no">NO</button>

   <h2>Discussion</h2>

   <!-- ... -->

 </section>
<!-- ... -->

앱 미리보기

73ca99ca35c13ee7.png

다음으로 버튼 클릭에 대한 리스너를 등록합니다. 사용자가 YES를 클릭하면 인증 UID를 사용하여 응답을 데이터베이스에 저장합니다.

  1. StackBlitz에서 index.js 파일로 이동합니다.
  2. 파일 맨 아래에 다음 코드를 추가하여 RSVP 상태를 수신합니다.
// ...

// Listen to RSVP responses
rsvpYes.onclick = () => {
}
rsvpNo.onclick = () => {
}
  1. attendees 라는 새 컬렉션을 만든 다음 RSVP 버튼을 클릭하면 문서 참조를 등록합니다.
  2. 클릭 한 버튼에 따라 해당 참조를 true 또는 false 로 설정합니다.

먼저 rsvpYes :

// ...

// Listen to RSVP responses
rsvpYes.onclick = () => {
 // Get a reference to the user's document in the attendees collection
 const userDoc = firebase.firestore().collection('attendees').doc(firebase.auth().currentUser.uid);

 // If they RSVP'd yes, save a document with attending: true
 userDoc.set({
   attending: true
 }).catch(console.error)
}

그런 다음 rsvpNo 대해서도 동일하지만 값은 false .

rsvpNo.onclick = () => {
 // Get a reference to the user's document in the attendees collection
 const userDoc = firebase.firestore().collection('attendees').doc(firebase.auth().currentUser.uid);

 // If they RSVP'd no, save a document with attending: false
 userDoc.set({
   attending: false
 }).catch(console.error)
}

규칙 추가

이미 몇 가지 규칙을 설정했기 때문에 버튼으로 추가하는 새 데이터는 거부됩니다. attendees 컬렉션에 추가 할 수 있도록 규칙을 업데이트해야합니다.

attendees 컬렉션의 경우 문서 이름으로 인증 UID를 사용 했으므로이를 uid 제출자의 uid 가 작성중인 문서와 동일한 지 확인할 수 있습니다. 모든 사람이 참석자 목록을 읽을 수 있도록 허용하지만 (개인 데이터가 없으므로) 작성자 만 업데이트 할 수 있어야합니다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }
  }
}

유효성 검사 규칙 추가

데이터 유효성 검사를 추가하여 예상되는 모든 필드가 문서에 있는지 확인합니다.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId
          && "attending" in request.resource.data;

    }
  }
}

(선택 사항) 이제 버튼 클릭 결과를 볼 수 있습니다. Firebase 콘솔에서 Cloud Firestore 대시 보드로 이동합니다.

RSVP 상태 읽기

이제 응답을 기록 했으므로 누가 오는지 확인하고 UI에 반영 해 보겠습니다.

  1. StackBlitz에서 index.html 파일로 이동합니다.
  2. description-container 에서 ID가 number-attending 새 요소를 추가합니다.
<!-- ... -->

 <section id="description-container">
     <!-- ... -->
     <p id="number-attending"></p>
 </section>

<!-- ... -->

다음으로 attendees 컬렉션에 대한 리스너를 등록하고 YES 응답 수를 계산합니다.

  1. StackBlitz에서 index.js 파일로 이동합니다.
  2. 파일 하단에 다음 코드를 추가하여 RSVP 상태를 듣고 YES 클릭을 계산합니다.
// ...
// Listen for attendee list
firebase.firestore()
.collection('attendees')
.where("attending", "==", true)
.onSnapshot(snap => {
 const newAttendeeCount = snap.docs.length;

 numberAttending.innerHTML = newAttendeeCount+' people going'; 
})
  1. 마지막으로 현재 상태에 해당하는 버튼을 강조 표시하겠습니다. 현재 인증 UID에 attendees 컬렉션에 항목이 있는지 확인한 다음 클래스를 clicked 로 설정합니다.
// ...
// Listen for attendee list
function subscribeCurrentRSVP(user){
 rsvpListener = firebase.firestore()
 .collection('attendees')
 .doc(user.uid)
 .onSnapshot((doc) => {
   if (doc && doc.data()){
     const attendingResponse = doc.data().attending;

     // Update css classes for buttons
     if (attendingResponse){
       rsvpYes.className="clicked";
       rsvpNo.className="";
     }
     else{
       rsvpYes.className="";
       rsvpNo.className="clicked";
     }
   }
 });
}
  1. 또한 탈퇴 기능을 만들어 보겠습니다. 사용자가 로그 아웃 할 때 사용됩니다.
// ...

function unsubscribeCurrentRSVP(){
 if (rsvpListener != null)
 {
   rsvpListener();
   rsvpListener = null;
 }
 rsvpYes.className="";
 rsvpNo.className="";
}
  1. 인증 리스너에서 함수를 호출합니다.
// ...

// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user) => {
if (user){
  startRsvpButton.textContent = "LOGOUT";
  // Show guestbook to logged-in users
  guestbookContainer.style.display = "block";

  // Subscribe to the guestbook collection
  subscribeGuestbook();
  // Subscribe to the guestbook collection
  subscribeCurrentRSVP(user);
}
else{
  startRsvpButton.textContent = "RSVP";
  // Hide guestbook for non-logged-in users
  guestbookContainer.style.display = "none";

  // Unsubscribe from the guestbook collection
  unsubscribeGuestbook();
  // Unsubscribe from the guestbook collection
  unsubscribeCurrentRSVP();

}
});
  1. 여러 사용자로 로그인을 시도하고 추가 버튼을 클릭 할 때마다 카운트가 증가하는 것을 확인하십시오.

앱 미리보기

3df607d3e0b3c35.png

Firebase를 사용하여 대화 형 실시간 웹 애플리케이션을 구축했습니다!

우리가 다룬 내용

  • Firebase 인증
  • FirebaseUI
  • Cloud Firestore
  • Firebase 보안 규칙
  • Firebase 호스팅

다음 단계

더 알아보기

어떻게 됐어?

여러분의 의견을 환영합니다! 여기에 (매우) 짧은 양식을 작성 하십시오 .