Firebase forWebについて知る

1。概要

このコードラボでは、あなたはの基礎のいくつかを学びますFirebaseをインタラクティブなWebアプリケーションを作成します。いくつかのFirebase製品を使用して、イベントの出欠確認とゲストブックのチャットアプリを作成します。

59abdefbcc23bbbe.png

あなたが学ぶこと

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

必要なもの

  • Chromeなどの選択したブラウザ。
  • アクセスstackblitz.com (なしアカウントまたはログイン必要)。
  • GmailアカウントのようなGoogleアカウント。 GitHubアカウントにすでに使用しているメールアカウントをお勧めします。これにより、StackBlitzの高度な機能を使用できます。
  • codelabのサンプルコード。コードを取得する方法については、次の手順を参照してください。

2.開始コードを取得します

このコードラボでは、あなたが使用してアプリを構築StackBlitz 、それに統合されたいくつかのFirebaseのワークフローを持っているオンラインエディタを。 Stackblitzは、ソフトウェアのインストールや特別なStackBlitzアカウントを必要としません。

StackBlitzを使用すると、プロジェクトを他のユーザーと共有できます。 StackBlitzプロジェクトのURLを持っている他の人は、あなたのコードを見てプロジェクトをフォークすることはできますが、StackBlitzプロジェクトを編集することはできません。

  1. 開始コードのために、このURLにアクセスします。 https://stackblitz.com/edit/firebase-gtk-web-start
  2. StackBlitzページの上部には、フォークをクリックします。 f5135360aef481cc.png

これで、独自のStackBlitzプロジェクトとして開始コードのコピーが作成されました。あなたが署名しなかったので、自分のアカウントが呼ばれ@anonymousが、プロジェクトは、ユニークなURLと一緒に、固有の名前を持っています。すべてのファイルと変更は、このStackBlitzプロジェクトに保存されます。

3.イベント情報を編集します

このコードラボの開始資料は、いくつかのスタイルシートやアプリの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

4.Firebaseプロジェクトを作成して設定します

イベント情報を表示することはゲストにとっては素晴らしいことですが、イベントを表示するだけでは誰にとってもあまり役に立ちません。このアプリにいくつかの動的機能を追加しましょう。このためには、Firebaseをアプリに接続する必要があります。 Firebaseの使用を開始するには、Firebaseプロジェクトを作成して設定する必要があります。

Firebaseプロジェクトを作成する

  1. サインインしFirebase
  2. Firebaseコンソールで、クリックプロジェクトを追加(またはプロジェクトを作成します)、その後、あなたのFirebaseプロジェクトFirebase-のWebコードラボに名前付けます。
    a67c239f8cc7f4b5.png
  3. プロジェクト作成オプションをクリックします。プロンプトが表示されたら、Firebaseの利用規約に同意します。このアプリではアナリティクスを使用しないため、Googleアナリティクスの設定はスキップしてください。

Firebaseプロジェクトの詳細については、参照Firebaseプロジェクトを理解します

コンソールでFirebase製品を有効にする

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

  • Firebase認証Firebase UIを簡単ユーザーが自分のアプリに署名することを可能にします。
  • クラウド上の構造化データを保存したときにデータの変更のインスタント通知を取得するためのクラウドFirestore。
  • Firebaseセキュリティルールは、データベースを確保します。

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

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

ユーザーがウェブアプリにログインできるようにするには、このコードラボのために電子メール/パスワードログインメソッドを使用します:

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

CloudFirestoreを有効にする

ウェブアプリが使用するクラウドFirestoreをチャットメッセージを保存し、新しいチャットメッセージを受信します。

Cloud Firestoreを有効にする:

  1. Firebaseコンソールの[ビルド]セクションで、Firestoreデータベース]クリックします。
  2. データベースの作成]クリックします。
    3ce19fd6467e51c5.png
  3. テストモードオプションの[開始]を選択します。セキュリティルールに関する免責事項をお読みください。テストモードでは、開発中にデータベースに自由に書き込むことができます。 [次へ]クリックします。
    56369cebb9300eb.png
  4. データベースの場所を選択します(デフォルトを使用できます)。ただし、この場所は後で変更できないことに注意してください。
    32f815f4648c3174.png
  5. [完了]クリックします。

5.Firebaseを追加して設定します

Firebaseプロジェクトを作成し、一部のサービスを有効にしたので、Firebaseを使用するコードと、使用するFirebaseプロジェクトを指定する必要があります。

Firebaseライブラリを追加する

アプリでFirebaseを使用するには、Firebaseライブラリをアプリに追加する必要があります。これを行うには複数の方法がありますが、 Firebaseドキュメントで説明します。たとえば、GoogleのCDNからライブラリを追加したり、npmを使用してローカルにインストールしてから、Browserifyを使用している場合はアプリにパッケージ化することができます。

StackBlitzは自動バンドルを提供するため、importステートメントを使用してFirebaseライブラリを追加できます。ライブラリのモジュラー(v9)バージョンを使用します。これは、「ツリーシェイク」と呼ばれるプロセスを通じてWebページの全体的なサイズを縮小するのに役立ちます。あなたは、モジュール式のSDKについて詳しく学ぶことができるドキュメントでは

このアプリをビルドするには、Firebase Authentication、FirebaseUI、CloudFirestoreライブラリを使用します。このコードラボでは、以下のimport文は、すでにの上部に含まれているindex.jsファイル、そして我々が行くように、私たちは各Firebaseライブラリから複数のメソッドをインポートすることがあります:

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

// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';

// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from '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
    const 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
    initializeApp(firebaseConfig);
    

6.ユーザーサインイン(RSVP)を追加します

今、あなたはアプリにFirebaseを追加したことを、あなたはレジスタの人々が使用していることをRSVPボタンに設定することができますFirebase認証を

電子メールサインインとFirebaseUIを使用してユーザーを認証します

ユーザーにメールアドレスでサインインするように求めるRSVPボタンが必要です。あなたはフックでこれを行うことができますFirebaseUIをRSVP button.FirebaseUIにあなたFirebaseのAuthの上に事前に構築されたUIを提供するライブラリです。

FirebaseUIは、設定(オプションで参照が必要ですマニュアルを参照して2つのことを行います):

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

FirebaseUIAuthを初期化するコードを追加します

  1. StackBlitzでは、に行くindex.jsファイル。
  2. 上部には、見つけfirebase/auth import文を、その後、追加getAuthEmailAuthProvider :そうのように、
    // ...
    // Add the Firebase products and methods that you want to use
    import { getAuth, EmailAuthProvider } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. 右後の認証オブジェクトへの参照保存initializeApp :そうのような、
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. FirebaseUI構成が開始コードですでに提供されていることに注意してください。電子メール認証プロバイダーを使用するように既に設定されています。
  5. 以下の下部にあるmain()関数index.js 、FirebaseUI初期化ステートメントを追加し、のようなので:
    async function main() {
      // ...
    
      // Initialize the FirebaseUI widget using Firebase
      const ui = new firebaseui.auth.AuthUI(auth);
    }
    main();
    
    

HTMLにRSVPボタンを追加する

  1. StackBlitzでは、に行くindex.htmlファイル。
  2. 内部RSVPボタン用のHTMLを追加しevent-details-container以下の例のように。

    同じ使用するように注意してくださいidこのコードラボのために、これらの特定のIDにフックが既に存在している、ので、以下のように値をindex.jsファイルは。

    注意していること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
  3. RSVPボタンでリスナーを設定し、FirebaseUI開始関数を呼び出します。これにより、FirebaseUIにサインインウィンドウを表示するように指示されます。

    以下の下に次のコードを追加しmain()関数index.js
    async function main() {
      // ...
    
      // Listen to RSVP button clicks
      startRsvpButton.addEventListener("click",
       () => {
            ui.start("#firebaseui-auth-container", uiConfig);
      });
    }
    main();
    

アプリへのサインインをテストする

  1. StackBlitzのプレビューウィンドウで、[出欠確認]ボタンをクリックしてアプリにサインインします。
    • このコードラボでは、このコードラボの電子メール検証手順を設定していないため、偽の電子メールアドレスを含め、任意の電子メールアドレスを使用できます。
    • あなたはというエラーメッセージが表示された場合auth/operation-not-allowedか、 The given sign-in provider is disabled for this Firebase project 、必ずサインインプロバイダーFirebaseコンソールのように電子メール/パスワードを有効にすることを作るために確認してください。
    アプリのプレビュー
    3024f90b52ad55fe.png
  2. 行く認証ダッシュボードFirebaseコンソールインチ[ユーザー]タブでは、あなたがアプリに署名するために入力したアカウント情報が表示されるはずです。 682fc0eca86a99fc.png

UIに認証状態を追加する

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

Firebase Authentication状態リスナーコールバックを使用します。このコールバックは、ユーザーのログインステータスが変更されるたびに通知されます。現在サインインしているユーザーがいる場合、アプリは「RSVP」ボタンを「ログアウト」ボタンに切り替えます。

  1. StackBlitzでは、に行くindex.jsファイル。
  2. 上部には、見つけfirebase/auth import文を、その後、追加signOutonAuthStateChanged :そうのように、
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. 以下の下部に次のコードを追加しmain()関数:
    async function main() {
      // ...
    
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
        } else {
          startRsvpButton.textContent = 'RSVP';
        }
      });
    }
    main();
    
  4. ボタンリスナーで、現在のユーザーがいるかどうかを確認し、ログアウトします。これを行うには、現在の置き換えstartRsvpButton.addEventListener以下に
    // ...
    // Called when the user clicks the RSVP button
    startRsvpButton.addEventListener('click', () => {
      if (auth.currentUser) {
        // User is signed in; allows user to sign out
        signOut(auth);
      } else {
        // No user is signed in; allows user to sign in
        ui.start('#firebaseui-auth-container', uiConfig);
      }
    });
    

さて、あなたのアプリケーション内のボタンは、ログアウトを表示する必要があり、それがクリックされていますときには、RSVPに切り替える必要があります。

アプリのプレビュー

4c540450924f1607.png

7. CloudFirestoreにメッセージを書き込みます

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

ユーザーがアプリで書くチャットメッセージを格納するには、使用しますクラウド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データベースのコレクション。具体的には、 addDoc方法は、に(自動的に生成されたIDを持つ)新しい文書にメッセージコンテンツ追加guestbookコレクション。

  1. StackBlitzでは、に行くindex.jsファイル。
  2. 上部には、見つけfirebase/firestore import文を、そして追加getFirestoreaddDoc 、およびcollection :そうのように、
    // ...
    
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {
      getFirestore,
      addDoc,
      collection
    } from 'firebase/firestore';
    
  3. 今、私たちはFirestoreへの参照節約できますdb後のオブジェクトの右initializeApp
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. 底部にmain()関数は、次のコードを追加します。

    注意auth.currentUser.uid Firebase認証がログインしているユーザーのすべてのために与えることが自動生成されたユニークなIDへの参照です。
    async function main() {
      // ...
    
      // Listen to the form submission
      form.addEventListener('submit', async e => {
        // Prevent the default form redirect
        e.preventDefault();
        // Write a new message to the database collection "guestbook"
        addDoc(collection(db, 'guestbook'), {
          text: input.value,
          timestamp: Date.now(),
          name: auth.currentUser.displayName,
          userId: auth.currentUser.uid
        });
        // clear message input field
        input.value = '';
        // Return false to avoid redirect
        return false;
      });
    }
    main();
    

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

あなただけの誰もがお客様のチャットを見たいと思っていません。チャットを保護するためにできることの1つは、サインインしたユーザーのみにゲストブックの表示を許可することです。それはあなた自身のアプリケーションのために、あなたもを使用してデータベースを確保したいと思う、と述べFirebaseセキュリティルール。 (セキュリティルールの詳細については、コードラボの後半にあります。)

  1. StackBlitzでは、に行くindex.jsファイル。
  2. 編集onAuthStateChanged非表示にリスナーをして、ゲストブックを示しています。
    // ...
    
    // Listen to the current Auth state
    onAuthStateChanged(auth, 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. そのような「ちょっとそこ!」とメッセージを入力し、[送信]クリックしてください。

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

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

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

Firebaseコンソール

713870af0b3b63c.png

8.メッセージを読む

メッセージを同期する

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

メッセージを表示するには、データが変更されたときにトリガーされるリスナーを追加してから、新しいメッセージを表示する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. 上部には、見つけfirebase/firestore 、その後の追加、インポート文をqueryorderBy 、およびonSnapshot :そうのように、
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. 以下の下部にはmain()関数で、データベース内のすべての文書(ゲストブックのメッセージ)をループに次のコードを追加します。このコードで何が起こっているかについて詳しくは、スニペットの下の情報をお読みください。
    async function main() {
      // ...
    
      // Create query for messages
      const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc'));
      onSnapshot(q, 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);
        });
      });
    }
    main();
    

データベース内のメッセージを聞くためには、使用して特定のコレクションのクエリを作成したcollection機能を。変更を待機する上記のコードguestbookチャットメッセージが格納される場所であるコレクション、。メッセージも使用して、日付順に並んでいorderBy('timestamp', 'desc')一番上に最新のメッセージを表示します。

onSnapshot使用するクエリとコールバック関数:関数は2つのパラメータを取ります。クエリに一致するドキュメントに変更があった場合、コールバック関数がトリガーされます。これは、メッセージが削除、変更、または追加された場合に発生する可能性があります。詳細については、クラウドFirestoreのマニュアルを

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

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

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

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

アプリのプレビュー

e30df0a9614bae7d.png

9.基本的なセキュリティルールを設定します

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

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

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

  1. Firebaseコンソールの[ビルド]セクションで、[ルール]タブを選択し、Firestoreデータベース]クリックします(またはこちらをクリックしてくださいルール]タブに直接移動します)。
  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に機能をguestbookListener変数。

    Firestore onSnapshotリスナーを返します。後でスナップショットリスナーをキャンセルするために使用することができますことを退会機能を。
    // ...
    // Listen to guestbook updates
    // Listen to guestbook updates
    function subscribeGuestbook() {
      const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc'));
      guestbookListener = onSnapshot(q, 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);
        });
      });
    }
    
  2. 呼ばれる新しい機能の下に追加unsubscribeGuestbook 。かどうかをチェックしguestbookListener変数がnullでない場合、リスナーをキャンセルする関数を呼び出します。
    // ...
    // Unsubscribe from guestbook updates
    function unsubscribeGuestbook() {
      if (guestbookListener != null) {
        guestbookListener();
        guestbookListener = null;
      }
    }
    

最後に、新しい機能を追加しonAuthStateChangedコールバック。

  1. 追加subscribeGuestbook()の下にあるif (user)
  2. 追加unsubscribeGuestbook()の下部にelseのステートメント。
    // ...
    // Listen to the current Auth state
    onAuthStateChanged(auth, 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();
      }
    });
    

10.ボーナスステップ:学んだことを実践する

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

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

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

  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. 上部には、見つけfirebase/firestore import文を、そして追加docsetDoc 、およびwhere 、そのような:
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot,
      doc,
      setDoc,
      where
    } from 'firebase/firestore';
    
  3. 以下の下部にあるmain()関数で、RSVP状況を聞くために、次のコードを追加します。
    async function main() {
      // ...
    
      // Listen to RSVP responses
      rsvpYes.onclick = async () => {
      };
      rsvpNo.onclick = async () => {
      };
    }
    main();
    
    
  4. 呼ばれる新しいコレクションを作成attendeesどちらかのRSVPのボタンがクリックされた場合、文書の参照を登録します。
  5. 参照することを設定しtrueまたはfalseどのボタンに応じて、をクリックします。

    まず、 rsvpYes
    // ...
    // Listen to RSVP responses
    rsvpYes.onclick = async () => {
      // Get a reference to the user's document in the attendees collection
      const userRef = doc(db, 'attendees', auth.currentUser.uid);
    
      // If they RSVP'd yes, save a document with attendi()ng: true
      try {
        await setDoc(userRef, {
          attending: true
        });
      } catch (e) {
        console.error(e);
      }
    };
    
    続いて、ために同じrsvpNoが、値を持つfalse
    rsvpNo.onclick = async () => {
      // Get a reference to the user's document in the attendees collection
      const userRef = doc(db, 'attendees', auth.currentUser.uid);
    
      // If they RSVP'd yes, save a document with attending: true
      try {
        await setDoc(userRef, {
          attending: false
        });
      } catch (e) {
        console.error(e);
      }
    };
    

ルールを追加する

すでにいくつかのルールが設定されているため、ボタンを使用して追加する新しいデータは拒否されます。あなたはに追加できるようにするルールを更新する必要があります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-containerのIDを持つ新しい要素を追加number-attending
    <!-- ... -->
    
     <section id="description-container">
         <!-- ... -->
         <p id="number-attending"></p>
     </section>
    
    <!-- ... -->
    

次に、のリスナーを登録しattendees収集とYES応答数を数えます:

  1. StackBlitzでは、に行くindex.jsファイル。
  2. 以下の下部にはmain()関数で、RSVPの状態に耳を傾け、YESのクリック数をカウントするには、次のコードを追加します。
    async function main() {
      // ...
    
      // Listen for attendee list
      const attendingQuery = query(
        collection(db, 'attendees'),
        where('attending', '==', true)
      );
      const unsubscribe = onSnapshot(attendingQuery, snap => {
        const newAttendeeCount = snap.docs.length;
        numberAttending.innerHTML = newAttendeeCount + ' people going';
      });
    }
    main();
    

最後に、現在のステータスに対応するボタンを強調表示しましょう。

  1. 現在の認証UIDは、内のエントリがあるかどうかをチェックし、その関数を作成attendeesコレクションは、その後にボタンクラスを設定clicked
    // ...
    // Listen for attendee list
    function subscribeCurrentRSVP(user) {
      const ref = doc(db, 'attendees', user.uid);
      rsvpListener = onSnapshot(ref, 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';
          }
        }
      });
    }
    
  2. また、退会する機能を作ってみましょう。これは、ユーザーがログアウトするときに使用されます。
    // ...
    function unsubscribeCurrentRSVP() {
      if (rsvpListener != null) {
        rsvpListener();
        rsvpListener = null;
      }
      rsvpYes.className = '';
      rsvpNo.className = '';
    }
    
  3. 認証リスナーから関数を呼び出します。
    // ...
    // Listen to the current Auth state
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
          // Show guestbook to logged-in users
          guestbookContainer.style.display = 'block';
    
          // Subscribe to the guestbook collection
          subscribeGuestbook();
          // Subcribe to the user's RSVP
          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();
        }
      });
    
  4. 複数のユーザーとしてログインを試してみて、各追加YESボタンをクリックするだけで、数の増加を参照してください。

アプリのプレビュー

3df607d3e0b3c35.png

11.おめでとうございます!

Firebaseを使用して、インタラクティブなリアルタイムWebアプリケーションを構築しました。

私たちがカバーしたこと

  • Firebase認証
  • FirebaseUI
  • クラウドファイヤーストア
  • Firebaseのセキュリティルール

次のステップ

  • 他のFirebase製品についてもっと知りたいですか?ユーザーがアップロードした画像ファイルを保存したいですか?または、ユーザーに通知を送信しますか?チェックアウトFirebaseのWebコードラボをWeb用のより多くのFirebase製品の詳細深さに入るコードラボのために。
  • Cloud Firestoreについて詳しく知りたいですか?サブコレクションとトランザクションについて知りたいですか?頭の上のクラウドFirestoreのWebコードラボクラウドFirestoreの詳細深さに入るコードラボのために。それとも、このチェックアウトクラウドFirestoreを知るためにYouTubeのシリーズを

もっと詳しく知る

どうだった?

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