Cloud Firestore 웹 Codelab

1. 槪要

目標

이 Codelab에서는 Cloud Firestore 로 驅動되는 레스토랑 推薦 웹 앱을 빌드합니다.

이미지 5.png

學習 內容

  • 웹 앱에서 Cloud Firestore로 데이터 읽기 및 쓰기
  • 實時間으로 Cloud Firestore 데이터의 變更事項 受信 待機
  • Firebase 認證 및 保安 規則을 使用하여 Cloud Firestore 데이터 保護
  • 複雜한 Cloud Firestore 쿼리 作成

必要한 項目

이 Codelab을 始作하기 前에 다음을 設置했는지 確認하세요.

2. Firebase 프로젝트 만들기 및 설정

Firebase 프로젝트 만들기

  1. Firebase Console 에서 프로젝트 追加 를 클릭한 後 Firebase 프로젝트의 이름을 FriendlyEats 로 指定합니다.

Firebase 프로젝트의 프로젝트 ID를 記憶합니다.

  1. 프로젝트 만들기 를 클릭합니다.

빌드할 애플리케이션은 웹에서 使用 可能한 몇 가지 Firebase 서비스를 使用합니다.

  • Firebase 引證 - 使用者를 쉽게 識別할 수 있음
  • Cloud Firestore : 클라우드에 構造化된 데이터를 貯藏하고 데이터가 업데이트되면 卽時 알림을 받습니다.
  • 政敵 애셋을 호스팅하고 提供하는 Firebase 호스팅

이 Codelab에서는 Firebase 호스팅을 이미 構成했습니다. 하지만 Firebase 認證 및 Cloud Firestore의 境遇 Firebase Console을 使用하여 서비스를 構成하고 使用 設定하는 方法을 案內해 드립니다.

匿名 引證 使用 設定

이 Codelab에서는 認證이 重點을 두지는 않지만 앱에 몇 가지 形式의 認證이 있어야 합니다. 여기서는 匿名 로그인 을 使用합니다. 卽, 使用者가 메시지를 表示하지 않고 自動으로 로그인됩니다.

匿名 로그인 을 使用 設定해야 합니다.

  1. Firebase Console의 왼쪽 探索 메뉴에서 빌드 섹션을 찾습니다.
  2. 引證 을 클릭한 後 로그인 方法 탭을 클릭합니다 (또는 여기를 클릭 하여 바로 移動).
  3. 匿名 로그인 提供業體를 使用 設定한 다음 貯藏 을 클릭합니다.

이미지 7.png

이렇게 하면 使用者가 웹 앱에 액세스할 때 애플리케이션에서 自動으로 使用者를 로그인 處理할 수 있습니다. 仔細한 內容은 匿名 引證 文書 를 參照하세요.

Cloud Firestore 使用 設定

이 앱은 Cloud Firestore를 使用하여 레스토랑 情報와 評點을 貯藏하고 受信합니다.

Cloud Firestore를 使用 設定해야 합니다. Firebase Console의 빌드 섹션에서 Firestore 데이터베이스 를 클릭합니다. Cloud Firestore 窓에서 데이터베이스 만들기 를 클릭합니다.

Cloud Firestore의 데이터에 對한 액세스는 保安 規則으로 制御됩니다. 이 Codelab의 뒷部分에서 規則에 關해 더 仔細히 說明하겠지만, 始作하려면 于先 데이터에 몇 가지 基本 規則을 設定해야 합니다. Firebase Console의 規則 탭 에서 다음 規則을 追加한 後 揭示 를 클릭합니다.

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      //
      // WARNING: These rules are insecure! We will replace them with
      // more secure rules later in the codelab
      //
      allow read, write: if request.auth != null;
    }
  }
}

위 規則은 데이터 액세스 權限을 로그인한 使用者로 制限하여 引證되지 않은 使用者가 읽거나 쓸 수 없도록 합니다. 이는 公開 액세스를 許容하는 것보다 낫지만 아직 安全하지는 않으므로 이 Codelab의 뒷部分에서 이러한 規則을 改善할 豫定입니다.

3. 샘플 코드 가져오기

命令줄에서 GitHub 貯藏所 를 클론합니다.

git clone https://github.com/firebase/friendlyeats-web

샘플 코드를 ? friendlyeats-web 디렉터리에 클론해야 합니다. 이제부터 다음 디렉터리에서 모든 命令語를 實行해야 합니다.

cd friendlyeats-web/vanilla-js

始作 앱 가져오기

IDE (WebStorm, Atom, Sublime, Visual Studio Code 等)를 使用하여 PENDING friendlyeats-web 디렉터리를 열거나 가져옵니다. 이 디렉터리에는 아직 作動하지 않는 食堂 推薦 앱으로 構成된 Codelab의 始作 코드가 包含되어 있습니다. 이 Codelab 全體에 걸쳐 앱이 作動하도록 만들 豫定이므로 곧 디렉터리의 코드를 修正해야 합니다.

4. Firebase 命令줄 인터페이스 設置

Firebase 命令줄 인터페이스 (CLI)를 使用하면 로컬에서 웹 앱을 提供하고 웹 앱을 Firebase 호스팅에 配布할 수 있습니다.

  1. 다음 npm 命令語를 實行하여 CLI를 設置합니다.
npm -g install firebase-tools
  1. 다음 命令語를 實行하여 CLI가 올바르게 設置되었는지 確認합니다.
firebase --version

Firebase CLI 버전이 v7.4.0 以上인지 確認합니다.

  1. 다음 命令語를 實行하여 Firebase CLI를 承認합니다.
firebase login

앱의 로컬 디렉터리 및 파일에서 Firebase 호스팅에 對한 앱 構成을 가져오도록 웹 앱 템플릿을 設定했습니다. 하지만 이렇게 하려면 앱을 Firebase 프로젝트와 連結해야 합니다.

  1. 命令줄에서 앱의 로컬 디렉터리에 액세스하는지 確認합니다.
  2. 다음 命令語를 實行하여 앱을 Firebase 프로젝트와 連結합니다.
firebase use --add
  1. 메시지가 標示되면 프로젝트 ID 를 選擇한 다음 Firebase 프로젝트에 別稱을 指定합니다.

別稱은 여러 環境 (프로덕션, 스테이징 等)이 있는 境遇에 有用합니다. 하지만 이 Codelab에서는 default 의 別稱을 使用해 보겠습니다.

  1. 命令줄의 나머지 案內를 따릅니다.

5. 로컬 서버 實行

이제 實際로 앱 作業을 始作할 準備가 되었습니다. 앱을 로컬에서 實行해 보겠습니다.

  1. 다음 Firebase CLI 命令語를 實行합니다.
firebase emulators:start --only hosting
  1. 命令줄에 다음과 같은 應答이 標示됩니다.
hosting: Local server: http://localhost:5000

Firebase 호스팅 에뮬레이터를 使用하여 로컬에서 앱을 提供합니다. 이제 http://localhost:5000 에서 웹 앱을 使用할 수 있습니다.

  1. http://localhost:5000 에서 앱을 엽니다.

Firebase 프로젝트에 連結된 FriendlyEats 寫本이 標示됩니다.

앱이 Firebase 프로젝트에 自動으로 連結되고 匿名 使用者로 自動 로그인됩니다.

이미지 2.png

6. Cloud Firestore에 데이터 쓰기

이 섹션에서는 앱의 UI를 채울 수 있도록 一部 데이터를 Cloud Firestore에 씁니다. 이 作業은 Firebase Console 을 통해 手動으로 할 수 있지만 基本的인 Cloud Firestore 쓰기를 보여주기 위해 앱 自體에서 遂行하겠습니다.

데이터 모델

Firestore 데이터는 컬렉션, 文書, 필드, 下位 컬렉션으로 分割됩니다. 各 레스토랑을 restaurants 라는 最上位 컬렉션에 文書로 貯藏합니다.

이미지 3.png

나중에 各 레스토랑 아래의 ratings 라는 下位 컬렉션에 各 리뷰를 貯藏합니다.

이미지 4.png

Firestore에 레스토랑 追加

앱의 基本 모델 客體는 레스토랑입니다. restaurants 컬렉션에 레스토랑 文書를 追加하는 코드를 作成해 보겠습니다.

  1. 다운로드한 파일에서 scripts/FriendlyEats.Data.js 를 엽니다.
  2. FriendlyEats.prototype.addRestaurant 函數를 찾습니다.
  3. 全體 函數를 다음 코드로 바꿉니다.

FriendlyEats.Data.js

FriendlyEats.prototype.addRestaurant = function(data) {
  var collection = firebase.firestore().collection('restaurants');
  return collection.add(data);
};

위의 코드는 restaurants 컬렉션에 새 文書를 追加합니다. 文書 데이터는 一般 자바스크립트 客體에서 가져옵니다. 먼저 Cloud Firestore 컬렉션 restaurants 에 對한 參照를 가져온 다음 데이터를 add '指定합니다.

食堂을 追加해 보세요.

  1. 브라우저의 FriendlyEats 앱으로 돌아가서 새로고침합니다.
  2. 毛의 데이터 追加 를 클릭합니다.

앱은 任意의 食堂 客體 세트를 自動으로 生成한 다음 addRestaurant 函數를 呼出합니다. 그러나 實際 웹 앱에는 아직 데이터가 標示되지 않습니다 . 如前히 데이터 檢索 (Codelab의 다음 섹션)을 具現해야 하기 때문입니다.

하지만 Firebase Console에서 Cloud Firestore 탭 으로 移動하면 이제 restaurants 컬렉션에 새 文書가 標示됩니다.

이미지 6.png

수고하셨습니다. 웹 앱에서 Cloud Firestore에 데이터를 作成했습니다.

다음 섹션에서는 Cloud Firestore에서 데이터를 檢索하여 앱에 標示하는 方法을 알아봅니다.

7. Cloud Firestore의 데이터 標示

이 섹션에서는 Cloud Firestore에서 데이터를 檢索하여 앱에 標示하는 方法을 알아봅니다. 두 가지 主要 段階는 쿼리 만들기와 스냅샷 리스너 追加입니다. 이 리스너는 쿼리와 一致하는 모든 旣存 데이터에 對한 알림을 받으며 實時間으로 업데이트를 受信합니다.

먼저 필터링되지 않은 基本 레스토랑 目錄을 提供할 쿼리를 만들어 보겠습니다.

  1. scripts/FriendlyEats.Data.js 파일로 돌아갑니다.
  2. FriendlyEats.prototype.getAllRestaurants 函數를 찾습니다.
  3. 全體 函數를 다음 코드로 바꿉니다.

FriendlyEats.Data.js

FriendlyEats.prototype.getAllRestaurants = function(renderer) {
  var query = firebase.firestore()
      .collection('restaurants')
      .orderBy('avgRating', 'desc')
      .limit(50);

  this.getDocumentsInQuery(query, renderer);
};

位 코드에서는 restaurants 이라는 最上位 컬렉션에서 平均 評點 (現在는 모두 0)에 따라 整列된 레스토랑을 最大 50個까지 檢索하는 쿼리를 生成합니다. 이 쿼리를 宣言한 後 데이터를 로드하고 렌더링하는 getDocumentsInQuery() 메서드에 傳達합니다.

스냅샷 리스너를 追加하여 이 作業을 遂行합니다.

  1. scripts/FriendlyEats.Data.js 파일로 돌아갑니다.
  2. FriendlyEats.prototype.getDocumentsInQuery 函數를 찾습니다.
  3. 全體 函數를 다음 코드로 바꿉니다.

FriendlyEats.Data.js

FriendlyEats.prototype.getDocumentsInQuery = function(query, renderer) {
  query.onSnapshot(function(snapshot) {
    if (!snapshot.size) return renderer.empty(); // Display "There are no restaurants".

    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        renderer.remove(change.doc);
      } else {
        renderer.display(change.doc);
      }
    });
  });
};

位 코드에서 query.onSnapshot 는 쿼리 結果가 變更될 때마다 콜백을 트리거합니다.

  • 처음에는 콜백이 쿼리의 全體 結果 集合, 卽 Cloud Firestore의 全體 restaurants 컬렉션과 함께 트리거됩니다. 그런 다음 모든 個別 文書를 renderer.display 函數에 傳達합니다.
  • 文書가 削除되면 change.type removed 입니다. 여기서는 UI에서 食堂을 削除하는 函數를 呼出합니다.

이제 두 메서드를 모두 具現했으므로 앱을 새로고침하고 앞서 Firebase Console에서 보았던 食堂이 이제 앱에 標示되는지 確認합니다. 이 섹션을 成功的으로 完了했다면 이제 앱이 Cloud Firestore로 데이터를 읽고 쓰는 것입니다.

레스토랑 目錄이 變更되면 이 리스너가 繼續 自動으로 업데이트됩니다. Firebase Console로 移動하여 食堂을 手動으로 削除하거나 이름을 變更해 보세요. 變更事項이 사이트에 卽時 標示되는 것을 確認할 수 있습니다.

이미지 5.png

8. Get() 데이터

只今까지 onSnapshot 를 使用하여 實時間으로 업데이트를 檢索하는 方法을 살펴봤습니다. 하지만 恒常 願하는 것은 아닙니다. 때로는 데이터를 한 番만 가져오는 것이 더 合理的입니다.

使用者가 앱에서 特定 食堂을 클릭할 때 트리거되는 메서드를 具現해 보겠습니다.

  1. scripts/FriendlyEats.Data.js 파일로 돌아갑니다.
  2. FriendlyEats.prototype.getRestaurant 函數를 찾습니다.
  3. 全體 函數를 다음 코드로 바꿉니다.

FriendlyEats.Data.js

FriendlyEats.prototype.getRestaurant = function(id) {
  return firebase.firestore().collection('restaurants').doc(id).get();
};

이 메서드를 具現하면 各 食堂의 페이지를 볼 수 있습니다. 目錄에서 食堂을 클릭하면 食堂의 細部情報 페이지가 標示됩니다.

이미지 1.png

只今은 이 Codelab에서 評點 追加를 具現해야 하므로 評點을 追加할 수 없습니다.

9. 데이터 整列 및 필터링

現在 앱은 食堂 目錄을 標示하지만 使用者가 必要에 따라 필터링할 수 있는 方法은 없습니다. 이 섹션에서는 Cloud Firestore의 高級 쿼리를 使用하여 필터링을 使用 設定합니다.

다음은 모든 Dim Sum 레스토랑을 가져오는 簡單한 쿼리의 例입니다.

var filteredQuery = query.where('category', '==', 'Dim Sum')

이름에서 알 수 있듯이 where() 메서드는 쿼리가 設定한 制限事項을 充足하는 필드가 있는 컬렉션의 멤버만 다운로드하도록 합니다. 여기서는 category Dim Sum 人 食堂만 다운로드합니다.

이 앱에서 使用者는 여러 필터를 連結하여 '샌프란시스코의 피자' 또는 '인기순 整列 로스앤젤레스의 海産物'과 같은 特定 쿼리를 만들 수 있습니다.

使用者가 選擇한 여러 基準을 基盤으로 레스토랑을 필터링하는 쿼리를 빌드하는 메서드를 만듭니다.

  1. scripts/FriendlyEats.Data.js 파일로 돌아갑니다.
  2. FriendlyEats.prototype.getFilteredRestaurants 函數를 찾습니다.
  3. 全體 函數를 다음 코드로 바꿉니다.

FriendlyEats.Data.js

FriendlyEats.prototype.getFilteredRestaurants = function(filters, renderer) {
  var query = firebase.firestore().collection('restaurants');

  if (filters.category !== 'Any') {
    query = query.where('category', '==', filters.category);
  }

  if (filters.city !== 'Any') {
    query = query.where('city', '==', filters.city);
  }

  if (filters.price !== 'Any') {
    query = query.where('price', '==', filters.price.length);
  }

  if (filters.sort === 'Rating') {
    query = query.orderBy('avgRating', 'desc');
  } else if (filters.sort === 'Reviews') {
    query = query.orderBy('numRatings', 'desc');
  }

  this.getDocumentsInQuery(query, renderer);
};

位 코드는 여러 where 필터와 單一 orderBy 절을 追加하여 使用者 入力을 基盤으로 複合 쿼리를 빌드합니다. 이제 쿼리는 使用者의 要求事項과 一致하는 食堂만 返還합니다.

브라우저에서 FriendlyEats 앱을 새로高枕韓 後 價格, 都市, 카테고리別로 필터링할 수 있는지 確認합니다. 테스트하는 동안 브라우저의 자바스크립트 콘솔에 다음과 같은 誤謬가 標示됩니다.

The query requires an index. You can create it here: https://console.firebase.google.com/project/project-id/database/firestore/indexes?create_composite=...

이러한 誤謬는 Cloud Firestore에서 大部分의 複合 쿼리에 對한 索引이 必要하기 때문입니다. 쿼리에 索引을 要求하면 規模에 따라 Cloud Firestore의 速度가 빨라집니다.

誤謬 메시지에서 링크를 열면 Firebase Console에서 올바른 媒介變數가 채워진 索引 生成 UI가 自動으로 열립니다. 다음 섹션에서는 이 애플리케이션에 必要한 索引을 作成하고 配布합니다.

10. 索引 配布

앱의 모든 經路를 探索하고 各 色인 生成 링크를 따라가고 싶지 않다면 Firebase CLI를 使用하여 한 番에 여러 索引을 쉽게 配布할 수 있습니다.

  1. 앱의 다운로드된 로컬 디렉터리에 firestore.indexes.json 파일이 있습니다.

이 파일은 可能한 모든 필터 組合에 必要한 모든 索引을 說明합니다.

firestore.indexes.json

{
 "indexes": [
   {
     "collectionGroup": "restaurants",
     "queryScope": "COLLECTION",
     "fields": [
       { "fieldPath": "city", "order": "ASCENDING" },
       { "fieldPath": "avgRating", "order": "DESCENDING" }
     ]
   },

   ...

 ]
}
  1. 다음 命令語를 使用하여 이러한 索引을 配布합니다.
firebase deploy --only firestore:indexes

몇 分 後 索引이 活性化되고 誤謬 메시지가 사라집니다.

11. 트랜잭션으로 데이터 쓰기

이 섹션에서는 使用者가 飮食店에 리뷰를 提出할 수 있는 機能을 追加합니다. 只今까지 모든 쓰기는 原子的이고 比較的 單純했습니다. 誤謬가 發生한 境遇 使用者에게 再試圖하라는 메시지를 標示하거나 앱에서 自動으로 쓰기를 재시도합니다.

앱에 食堂 評點을 追加하고 싶은 使用者가 많을 것이므로 여러 읽기 및 쓰기를 調整해야 합니다. 먼저 리뷰를 提出해야 합니다. 그런 다음 食堂의 評點( count , average rating )을 업데이트해야 합니다. 둘 中 하나가 失敗하지만 다른 하나는 失敗하지 않으면 데이터베이스의 한 部分에 있는 데이터가 다른 部分의 데이터와 一致하지 않는 一貫되지 않은 狀態가 됩니다.

多幸히 Cloud Firestore는 單一 原子的 作業에서 여러 읽기 및 쓰기를 遂行할 수 있는 트랜잭션 機能을 提供하여 데이터의 一貫性을 保障합니다.

  1. scripts/FriendlyEats.Data.js 파일로 돌아갑니다.
  2. FriendlyEats.prototype.addRating 函數를 찾습니다.
  3. 全體 函數를 다음 코드로 바꿉니다.

FriendlyEats.Data.js

FriendlyEats.prototype.addRating = function(restaurantID, rating) {
  var collection = firebase.firestore().collection('restaurants');
  var document = collection.doc(restaurantID);
  var newRatingDocument = document.collection('ratings').doc();

  return firebase.firestore().runTransaction(function(transaction) {
    return transaction.get(document).then(function(doc) {
      var data = doc.data();

      var newAverage =
          (data.numRatings * data.avgRating + rating.rating) /
          (data.numRatings + 1);

      transaction.update(document, {
        numRatings: data.numRatings + 1,
        avgRating: newAverage
      });
      return transaction.set(newRatingDocument, rating);
    });
  });
};

位 블록에서는 食堂 文書의 avgRating numRatings 의 數字 값을 업데이트하는 트랜잭션을 트리거합니다. 同時에 새 rating ratings 下位 컬렉션에 追加합니다.

12. 데이터 保安

이 Codelab을 始作할 때 모든 읽기 또는 쓰기를 위해 데이터베이스를 完全히 열도록 앱의 保安 規則을 設定했습니다. 實際 애플리케이션에서는 願치 않는 데이터 액세스나 修正을 防止하기 위해 훨씬 더 細分化된 規則을 設定할 수 있습니다.

  1. Firebase Console의 빌드 섹션에서 Firestore 데이터베이스 를 클릭합니다.
  2. Cloud Firestore 섹션에서 規則 탭을 클릭합니다. 또는 여기를 클릭 하여 바로 移動합니다.
  3. 基本값을 다음 規則으로 바꾸고 揭示 를 클릭합니다.

firestore.rules

rules_version = '2';
service cloud.firestore {

  // Determine if the value of the field "key" is the same
  // before and after the request.
  function unchanged(key) {
    return (key in resource.data) 
      && (key in request.resource.data) 
      && (resource.data[key] == request.resource.data[key]);
  }

  match /databases/{database}/documents {
    // Restaurants:
    //   - Authenticated user can read
    //   - Authenticated user can create/update (for demo purposes only)
    //   - Updates are allowed if no fields are added and name is unchanged
    //   - Deletes are not allowed (default)
    match /restaurants/{restaurantId} {
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update: if request.auth != null
                    && (request.resource.data.keys() == resource.data.keys()) 
                    && unchanged("name");
      
      // Ratings:
      //   - Authenticated user can read
      //   - Authenticated user can create if userId matches
      //   - Deletes and updates are not allowed (default)
      match /ratings/{ratingId} {
        allow read: if request.auth != null;
        allow create: if request.auth != null
                      && request.resource.data.userId == request.auth.uid;
      }
    }
  }
}

이러한 規則은 클라이언트가 安全한 변경만 遂行할 수 있도록 액세스를 制限합니다. 例를 들면 다음과 같습니다.

  • 食堂 文書를 업데이트하면 評點만 變更할 수 있으며 이름이나 다른 不變 데이터는 變更할 수 없습니다.
  • 使用者 ID가 로그인한 使用者와 一致하는 境遇에만 評點을 生成할 수 있으므로 스푸핑을 防止합니다.

Firebase Console을 使用하는 代身 Firebase CLI를 使用하여 Firebase 프로젝트에 規則을 配布할 수 있습니다. 作業 디렉터리의 firestore.rules 파일에는 이미 위의 規則이 包含되어 있습니다. Firebase Console을 使用하지 않고 로컬 파일 시스템에서 이러한 規則을 配布하려면 다음 命令語를 實行합니다.

firebase deploy --only firestore:rules

13. 結論

이 Codelab에서는 Cloud Firestore로 基本 및 高級 읽기 및 쓰기를 遂行하는 方法과 保安 規則으로 데이터 액세스를 保護하는 方法을 알아봤습니다. 全體 솔루션은 quickstarts-js 貯藏所 에서 確認할 수 있습니다.

Cloud Firestore에 對해 仔細히 알아보려면 다음 리소스를 參照하세요.

14. [選擇事項] 앱 체크로 適用

Firebase 앱 체크 는 앱에 對한 願치 않는 트래픽을 檢證하고 防止하여 保護 機能을 提供합니다. 이 段階에서는 reCAPTCHA Enterprise 로 앱 체크를 追加하여 서비스에 對한 액세스를 保護합니다.

먼저 앱 체크와 reCAPTCHA를 使用 設定해야 합니다.

reCaptcha Enterprise 使用 設定

  1. Cloud 콘솔의 保安에서 reCaptcha Enterprise 를 찾아 選擇합니다.
  2. 標示되는 메시지에 따라 서비스를 使用 設定하고 키 만들기 를 클릭합니다.
  3. 標示되는 메시지에 따라 標示 이름을 入力하고 플랫폼 類型으로 웹사이트 를 選擇합니다.
  4. 配布된 URL을 도메인 目錄 에 追加하고 '체크박스 챌린지 使用' 옵션이 選擇 解除 되어 있는지 確認합니다.
  5. 키 만들기 를 클릭하고 生成된 키를 安全하게 保管합니다. 이 段階의 後半部에서 必要합니다.

앱 체크 使用 設定

  1. Firebase Console의 왼쪽 패널에 있는 빌드 섹션을 찾습니다.
  2. 앱 체크 를 클릭한 다음 始作하기 버튼을 클릭합니다 (또는 콘솔 로 바로 리디렉션).
  3. 登錄 을 클릭하고 메시지가 標示되면 reCaptcha Enterprise 키를 入力한 다음 貯藏 을 클릭합니다.
  4. API 보기에서 貯藏所 를 選擇하고 適用 을 클릭합니다. Cloud Firestore 에도 同一한 作業을 遂行합니다.

이제 앱 체크가 適用됩니다. 앱을 새로고침하고 食堂을 만들거나 確認해 봅니다. 다음과 같은 誤謬 메시지가 標示됩니다.

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

卽, 앱 체크에서 基本的으로 檢證되지 않은 要請을 遮斷합니다. 이제 앱에 有效性 檢査를 追加해 보겠습니다.

FriendlyEats.View.js 파일로 移動한 다음 initAppCheck 函數를 업데이트하고 reCaptcha 키를 追加하여 앱 체크를 初期化합니다.

FriendlyEats.prototype.initAppCheck = function() {
    var appCheck = firebase.appCheck();
    appCheck.activate(
    new firebase.appCheck.ReCaptchaEnterpriseProvider(
      /* reCAPTCHA Enterprise site key */
    ),
    true // Set to true to allow auto-refresh.
  );
};

appCheck 인스턴스는 키와 함께 ReCaptchaEnterpriseProvider 로 初期化되며 isTokenAutoRefreshEnabled 는 앱에서 토큰을 自動으로 새로高枕하도록 許容합니다.

로컬 테스트를 使用 設定하려면 FriendlyEats.js 파일에서 앱이 初期化된 섹션을 찾아 다음 줄을 FriendlyEats.prototype.initAppCheck 函數에 追加합니다.

if(isLocalhost) {
  self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
}

이렇게 하면 로컬 웹 앱의 콘솔에 다음과 비슷한 디버그 토큰이 記錄됩니다.

App Check debug token: 8DBDF614-649D-4D22-B0A3-6D489412838B. You will need to add it to your app's App Check settings in the Firebase console for it to work.

이제 Firebase Console에서 앱 체크의 앱 뷰 로 移動합니다.

더보기 메뉴를 클릭하고 디버그 토큰 管理 를 選擇합니다.

그런 다음 디버그 토큰 追加 를 클릭하고 標示되는 메시지에 따라 콘솔에서 디버그 토큰을 붙여넣습니다.

수고하셨습니다. 이제 앱 체크가 앱에서 作動합니다.