Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。
このページは Cloud Translation API によって翻訳されました。
Switch to English

Firebase forWebについて知る

このコードラボでは、インタラクティブなウェブアプリケーションを作成するためのFirebaseの基本をいくつか学びます。いくつかのFirebase製品を使用して、イベントRSVPとゲストブックチャットアプリを構築してデプロイします。

59abdefbcc23bbbe.png

あなたが学ぶこと

  • FirebaseAuthenticationとFirebaseUIを使用してユーザーを認証します。
  • CloudFirestoreを使用してデータを同期します。
  • データベースを保護するためのFirebaseセキュリティルールを作成します。
  • FirebaseHostingにウェブアプリをデプロイします。

必要なもの

  • 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ページの上部で、[フォーク]をクリックします。 f5135360aef481cc.png

これで、独自のStackBlitzプロジェクトとして開始コードのコピーが作成されました。サインインしなかったため、アカウントの名前は@anonymousになりますが、プロジェクトには一意の名前と一意のURLがあります。すべてのファイルと変更は、このStackBlitzプロジェクトに保存されます。

このコードラボの開始資料は、いくつかのスタイルシートやアプリのHTMLコンテナーなど、Webアプリの構造を提供します。このコードラボの後半で、これらのコンテナを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の利用規約に同意します。このアプリではアナリティクスを使用しないため、Googleアナリティクスの設定はスキップしてください。

Firebaseプロジェクトの詳細については「Firebaseプロジェクト理解する」をご覧ください。

構築しているアプリは、ウェブアプリで利用できるいくつかのFirebase製品を使用しています。

  • FirebaseAuthenticationFirebaseUIにより、ユーザーはアプリに簡単にログインできます。
  • 構造化データをクラウドに保存し、データが変更されたときに即座に通知を受け取るCloudFirestore。
  • データベースを保護するためのFirebaseセキュリティルール
  • アセットをホストして提供するFirebaseHosting

これらの製品の一部は、特別な構成が必要であるか、Firebaseコンソールを使用して有効にする必要があります。

Firebase認証のメールサインインを有効にする

ユーザーがWebアプリにサインインできるようにするには、このコードラボで電子メール/パスワードのサインイン方法を使用します。

  1. Firebaseコンソールで、左側のパネルの[開発]をクリックします。
  2. 認証]クリックし、[サインインのメソッドタブをクリックします(または、こちらをクリックしてくださいサインインのメソッドタブに直接移動します)。
  3. [サインインプロバイダー]リストで[電子メール/パスワード]をクリックし、[有効にする]スイッチをオンの位置に設定して、[保存]をクリックします4c88427cfd869bee.png

CloudFirestoreを有効にする

Webアプリは、 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 Authentication、FirebaseUI、CloudFirestoreライブラリを使用します。このコードラボでは、 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";

FirebaseWebアプリをプロジェクトに追加します

  1. Firebaseコンソールに戻り、左上の[プロジェクトの概要]をクリックして、プロジェクトの概要ページに移動します。
  2. プロジェクトの概要ページの中央にあるWebアイコンをクリックしますb286f3d215e1f578.png新しいFirebaseWebアプリを作成します。 c167e9526fad2825.png
  3. ニックネームWebアプリケーションでアプリを登録します。
  4. このコードラボで、[このアプリのFirebaseホスティングも設定する]の横にあるチェックボックスをオンにしないでください。ここでは、StackBlitzのプレビューペインを使用します。
  5. [アプリの登録]をクリックします。 c85ac8aa351e2560.png
  6. Firebase設定オブジェクトをクリップボードにコピーしますed1e598c6132f734.png
  7. [続行]をクリックしてコンソールに移動します。

Firebase構成オブジェクトをアプリに追加します。

  1. StackBlitzに戻り、 index.jsファイルに移動します。
  2. Add Firebase project configuration object hereコメント行で見つけ、構成スニペットをコメントのすぐ下に貼り付けます。
  3. initializeApp関数呼び出しを追加して、独自のFirebaseプロジェクト構成を使用してFirebaseをセットアップします。
// ...

// 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は、FirebaseAuthの上に構築済みのUIを提供するライブラリです。

FirebaseUIには、次の2つのことを行う構成( ドキュメントのオプションを参照)が必要です。

  1. 電子メール/パスワードのサインイン方法を使用することをFirebaseUIに通知します。
  2. サインインが成功した場合のコールバックを処理し、リダイレクトを回避するためにfalseを返します。単一ページのWebアプリを構築しているため、ページを更新したくありません。

まず、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]ボタンをクリックしてアプリにサインインします。
  • このコードラボでは、このコードラボの電子メール検証手順を設定していないため、偽の電子メールアドレスを含め、任意の電子メールアドレスを使用できます。
  • The given sign-in provider is disabled for this Firebase projectauth/operation-not-allowedまたはThe given sign-in provider is disabled for this Firebase projectことを示すエラーメッセージが表示された場合は、FirebaseコンソールでサインインプロバイダーとしてEメール/パスワードが有効になっていることを確認してください。
  1. Firebaseコンソールの認証ダッシュボードに移動します。 [ユーザー]タブに、アプリにサインインするために入力したアカウント情報が表示されます。

アプリのプレビュー

3024f90b52ad55fe.png

682fc0eca86a99fc.png

UIに認証状態を追加する

ここで、UIにサインインしているという事実が反映されていることを確認してください。

Firebase Authentication状態リスナーコールバックを使用します。これは、ユーザーのサインインステータスが変更されるたびに通知されます。現在ユーザーがいる場合は、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を次のように置き換えます。
// ...
// 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

ユーザーが来ていることを知っているのは素晴らしいことですが、アプリでゲストに何か他のことをしてもらいましょう。ゲストブックにメッセージを残すことができたらどうでしょうか。彼らは、なぜ彼らが来ることに興奮しているのか、誰に会いたいのかを共有することができます。

ユーザーがアプリに書き込んだチャットメッセージを保存するには、 CloudFirestoreを使用します。

データ・モデル

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

ユーザーが[送信]ボタンをクリックすると、以下のコードスニペットがトリガーされます。メッセージ入力フィールドの内容をデータベースのguestbookコレクションに追加します。具体的には、 addメソッドは、メッセージコンテンツを(自動生成されたIDを持つ)新しいドキュメントのguestbookコレクションに追加します。

  1. StackBlitzで、 index.jsファイルに移動します。
  2. ファイルの最後に、次のコードを追加します。

firebase.auth().currentUser.uidは、FirebaseAuthenticationがすべてのログインユーザーに提供する自動生成された一意の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;
});

サインインしたユーザーにのみゲストブックを表示する

ゲストのチャットをにも見られたくない。チャットを保護するためにできることの1つは、サインインしたユーザーのみにゲストブックの表示を許可することです。とはいえ、独自のアプリの場合は、 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. 「Heythere!」などのメッセージを入力し、[送信]をクリックします。

このアクションにより、メッセージがCloudFirestoreデータベースに書き込まれます。ただし、データの取得を実装する必要があるため、実際のWebアプリにはまだメッセージが表示されません。次にそれを行います。

ただし、Firebaseコンソールに新しく追加されたメッセージが表示されます。

Firebaseコンソールのデータベースダッシュボードに、新しく追加されたメッセージを含むguestbookコレクションが表示されます。メッセージを送信し続けると、ゲストブックコレクションには次のような多くのドキュメントが含まれます。

Firebaseコンソール

713870af0b3b63c.png

メッセージを同期する

ゲストがデータベースにメッセージを書き込むことができるのは素晴らしいことですが、アプリではまだメッセージを見ることができません。

メッセージを表示するには、データが変更されたときにトリガーされるリスナーを追加してから、新しいメッセージを表示するUI要素を作成する必要があります。

アプリから新しく追加されたメッセージをリッスンするコードを追加します。まず、メッセージを表示するセクションをHTMLに追加します。

  1. StackBlitzで、 index.htmlファイルに移動します。
  2. ではguestbook-containerのIDを持つ新しいセクションを追加guestbook
<!-- ... -->

  <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関数は、コールバック関数という1つのパラメーターを取ります。クエリに一致するドキュメントに変更があった場合、コールバック関数がトリガーされます。これは、メッセージが削除、変更、または追加された場合に発生する可能性があります。詳細については、 CloudFirestoreのドキュメントを参照してください。

同期メッセージをテストする

Cloud Firestoreは、データベースにサブスクライブしているクライアントとデータを自動的かつ即座に同期します。

  1. データベースで以前に作成したメッセージは、アプリに表示されます。新しいメッセージを自由に書いてください。それらは即座に表示されるはずです。
  2. ワークスペースを複数のウィンドウまたはタブで開くと、メッセージはタブ間でリアルタイムに同期されます。
  3. (オプション) Firebaseコンソールの[データベース]セクションで、新しいメッセージを手動で直接削除、変更、または追加してみることができます。変更はUIに表示されます。

おめでとう!アプリでCloudFirestoreドキュメントを読んでいます!

アプリのレビュー

e30df0a9614bae7d.png

最初に、テストモードを使用するようにCloud Firestoreを設定しました。つまり、データベースは読み取りと書き込みのために開かれています。ただし、テストモードは、開発のごく初期の段階でのみ使用する必要があります。ベストプラクティスとして、アプリを開発するときにデータベースのセキュリティルールを設定する必要があります。セキュリティは、アプリの構造と動作に不可欠である必要があります。

セキュリティルールを使用すると、データベース内のドキュメントとコレクションへのアクセスを制御できます。柔軟なルール構文を使用すると、データベース全体へのすべての書き込みから特定のドキュメントの操作まで、あらゆるものに一致するルールを作成できます。

FirebaseコンソールでCloudFirestoreのセキュリティルールを記述できます。

  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という新しい関数にプルしsubscribeGuestbook 。また、 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. 呼ばれる新しい機能の下に追加unsubscribeGuestbookguestbookListener変数がnullでないかどうかを確認してから、関数を呼び出してリスナーをキャンセルします。
// ...
// Unsubscribe from guestbook updates
function unsubscribeGuestbook(){
 if (guestbookListener != null)
 {
   guestbookListener();
   guestbookListener = null;
 }
};
  1. 最後に、新しい関数をonAuthStateChangedコールバックに追加します(次の2つの手順を使用します)。
  2. if (user)下部にsubscribeGuestbook()を追加しsubscribeGuestbook()
  3. elseステートメントの最後にunsubscribeGuestbook()を追加しelse
// ...
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)を使用して、ファイルとホスティング設定をFirebaseHostingにデプロイできます。ただし、このコードラボでは、FirebaseCLIをワークスペースに統合したStackBlitzを使用しています。

StackBlitzのFirebase統合を使用して、アセットをデプロイするFirebaseプロジェクトをStackBlitzに指示できます。

  1. StackBlitzでGitHubにまだサインインしていない場合は、右上の[サインイン]をクリックて、GitHubアカウントの資格情報を入力します。

99a41778bb3c194c.png

  • すでにGitHubアカウントをお持ちの場合は、GitHubアカウントを使用してサインインしてください。
  • GitHubアカウントをまだお持ちでない場合は、Firebaseへのログインに使用したのと同じメールアドレスを使用してGitHubアカウントを作成してください。
  1. 左側のパネルにFirebaseアイコンが表示されます。

2981c2e3ad13c2c1.png 3. [ Googleにサインイン]をクリックします。 Firebaseへのログインに使用したのと同じメールアドレスを使用してログインします。 4. Firebaseプロジェクトのリストから、 Firebase-Web-Codelabプロジェクトを選択します。

StackBlitzを使用したFirebaseHostingへのデプロイは、文字通りワンクリック操作です。

  1. StackBlitzワークスペースで、ページの左側にある[デプロイ]をクリックします。うん、それだけです。ワンステップ! 8fe6c0bfc04c8935.png

Firebase Hostingの仕組みについて詳しくは、ドキュメントをご覧ください。

プロジェクトのFirebaseコンソールの[ホスティング]セクションに移動して、デプロイの履歴、アプリの以前のバージョンにロールバックする機能、カスタムドメインを設定するワークフローなど、役立つホスティング情報とツールを表示します。

出席者の出欠確認ステータスを記録する

現在、アプリでは、イベントに興味がある場合にチャットを開始できます。また、誰かが来ているかどうかを知る唯一の方法は、チャットに投稿するかどうかです。整理整頓して、何人の人が来るのかを知らせましょう。

トグルを追加して、イベントに参加したい人を登録し、来ている人の数を収集します。

  1. StackBlitzで、 index.htmlファイルに移動します。
  2. guestbook-containerに、次のように[はい]ボタンと[いいえ]ボタンのセットを追加します。
<!-- ... -->
  <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

次に、ボタンクリックのリスナーを登録します。ユーザーが[はい]をクリックした場合は、認証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が作成中のドキュメントと同じであることを確認できます。参加者リストは誰でも読むことができますが(個人データがないため)、更新できるのは作成者だけです。

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コンソールでCloudFirestoreダッシュボードに移動します。

RSVPステータスの読み取り

応答を記録したので、誰が来るのかを確認し、UIに反映させましょう。

  1. StackBlitzで、 index.htmlファイルに移動します。
  2. description-containernumber-attending 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設定し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を使用して、インタラクティブなリアルタイムWebアプリケーションを構築しました。

私たちがカバーしたこと

  • Firebase認証
  • FirebaseUI
  • Cloud Firestore
  • Firebaseのセキュリティルール
  • Firebaseホスティング

次のステップ

もっと詳しく知る

どうだった?

フィードバックをお待ちしております。ここで(非常に)短いフォームに記入してください。