FirebaseWebコードラボ

1。概要

このコードラボでは、Firebaseの製品とサービスを使用してチャットクライアントを実装およびデプロイすることにより、 Firebaseを使用してWebアプリケーションを簡単に作成する方法を学習します。

3b1284f5144b54f6.png

あなたが学ぶこと

  • CloudFirestoreとCloudStorage forFirebaseを使用してデータを同期します。
  • FirebaseAuthenticationを使用してユーザーを認証します。
  • WebアプリをFirebaseHostingにデプロイします。
  • Firebase CloudMessagingを使用して通知を送信します。
  • Webアプリのパフォーマンスデータを収集します。

必要なもの

  • WebStormAtomSublimeVSCodeなどの選択したIDE /テキストエディター
  • パッケージマネージャーnpm 。通常はNode.jsに付属しています。
  • ターミナル/コンソール
  • Chromeなどの選択したブラウザ
  • コードラボのサンプルコード(コードの取得方法については、コードラボの次のステップを参照してください)。

2.サンプルコードを取得します

コマンドラインからcodelabのGitHubリポジトリのクローンを作成します。

git clone https://github.com/firebase/codelab-friendlychat-web

または、gitがインストールされていない場合は、リポジトリをZIPファイルとしてダウンロードできます。

スターターアプリをインポートする

IDEを使用して、複製されたリポジトリから📁web web-startディレクトリを開くかインポートします。この📁web web-startディレクトリには、完全に機能するチャットWebアプリとなるcodelabの開始コードが含まれています。

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

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

  1. Firebaseにログインします。
  2. Firebaseコンソールで、[プロジェクトの追加]をクリックし、FirebaseプロジェクトにFriendlyChatという名前を付けます。 FirebaseプロジェクトのプロジェクトIDを覚えておいてください。
  3. [このプロジェクトでGoogleAnalyticsを有効にする]のチェックを外します
  4. [プロジェクトの作成]をクリックします。

構築するアプリケーションは、ウェブアプリで利用できるFirebase製品を使用しています。

  • ユーザーがアプリに簡単にログインできるようにするFirebase認証
  • 構造化データをクラウドに保存し、データが変更されたときに即座に通知を受け取るCloudFirestore。
  • クラウドにファイルを保存するためのFirebase用クラウドストレージ
  • アセットをホストして提供するFirebaseHosting
  • プッシュ通知を送信し、ブラウザのポップアップ通知を表示するFirebase CloudMessaging
  • アプリのユーザーパフォーマンスデータを収集するためのFirebasePerformanceMonitoring

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

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

  1. Webアイコンをクリックします58d6543a156e56f9.png新しいFirebaseWebアプリを作成します。
  2. ニックネームFriendlyChatでアプリを登録し、[このアプリのFirebaseHostingも設定する]の横にあるチェックボックスをオンにします。 [アプリの登録]をクリックします。
  3. 次のステップでは、構成オブジェクトが表示されます。 JSオブジェクト(周囲のHTMLではない)のみをfirebase-config.jsにコピーします

Webアプリのスクリーンショットを登録する

Firebase認証でGoogleログインを有効にする

ユーザーが自分のGoogleアカウントでウェブアプリにログインできるようにするために、 Googleのログイン方法を使用します。

Googleログインを有効にする必要があります。

  1. Firebaseコンソールで、左側のパネルの[ビルド]セクションを見つけます。
  2. [認証]をクリックし、[サインイン方法]タブをクリックします(または、ここをクリックして直接アクセスします)。
  3. Googleサインインプロバイダーを有効にして、[保存]をクリックします。
  4. アプリの公開名をFriendlyChatに設定し、ドロップダウンメニューからプロジェクトサポートメールを選択します。
  5. Google Cloud ConsoleでOAuth同意画面を設定し、ロゴを追加します。

d89fb3873b5d36ae.png

CloudFirestoreを有効にする

Webアプリは、 Cloud Firestoreを使用してチャットメッセージを保存し、新しいチャットメッセージを受信します。

CloudFirestoreを有効にする必要があります。

  1. Firebaseコンソールの[ビルド]セクションで、[ Firestoreデータベース]をクリックします。
  2. CloudFirestoreペインでデータベースの作成をクリックします。

729991a081e7cd5.png

  1. [テストモードで開始]オプションを選択し、セキュリティルールに関する免責事項を読んだ後、[次へ]をクリックします。

テストモードでは、開発中にデータベースに自由に書き込むことができます。このコードラボの後半で、データベースをより安全にします。

77e4986cbeaf9dee.png

  1. CloudFirestoreデータが保存される場所を設定します。これをデフォルトのままにするか、近くの地域を選択できます。 [完了]をクリックして、Firestoreをプロビジョニングします。

9f2bb0d4e7ca49c7.png

クラウドストレージを有効にする

ウェブアプリはCloudStorage for Firebaseを使用して、写真を保存、アップロード、共有します。

クラウドストレージを有効にする必要があります。

  1. Firebaseコンソールの[ビルド]セクションで、[ストレージ]をクリックします。
  2. [開始]ボタンがない場合は、クラウドストレージがすでに有効になっていることを意味し、以下の手順を実行する必要はありません。
  3. [開始]をクリックします。
  4. Firebaseプロジェクトのセキュリティルールに関する免責事項を読み、[次へ]をクリックします。

デフォルトのセキュリティルールを使用すると、認証されたユーザーは誰でもCloudStorageに何でも書き込むことができます。このコードラボの後半で、ストレージをより安全にします。

62f1afdcd1260127.png

  1. Cloud Storageの場所は、CloudFirestoreデータベースに選択したのと同じリージョンで事前に選択されています。 [完了]をクリックしてセットアップを完了します。

1d7f49ebaddb32fc.png

4.Firebaseコマンドラインインターフェースをインストールします

Firebaseコマンドラインインターフェース(CLI)を使用すると、Firebase Hostingを使用してウェブアプリをローカルで提供したり、ウェブアプリをFirebaseプロジェクトにデプロイしたりできます。

  1. 次のnpmコマンドを実行してCLIをインストールします。
npm -g install firebase-tools
  1. 次のコマンドを実行して、CLIが正しくインストールされていることを確認します。
firebase --version

FirebaseCLIのバージョンがv4.1.0以降であることを確認してください。

  1. 次のコマンドを実行して、FirebaseCLIを承認します。
firebase login

アプリのローカルディレクトリ(コードラボで以前に複製したリポジトリ)からFirebaseHostingのアプリの構成をプルするようにウェブアプリテンプレートを設定しました。ただし、構成をプルするには、アプリをFirebaseプロジェクトに関連付ける必要があります。

  1. コマンドラインがアプリのローカルweb-startディレクトリにアクセスしていることを確認してください。
  2. 次のコマンドを実行して、アプリをFirebaseプロジェクトに関連付けます。
firebase use --add
  1. プロンプトが表示されたら、プロジェクトIDを選択し、Firebaseプロジェクトにエイリアスを指定します。

エイリアスは、複数の環境(本番環境、ステージングなど)がある場合に役立ちます。ただし、このコードラボでは、 defaultのエイリアスを使用してみましょう。

  1. コマンドラインの残りの指示に従います。

5.スターターアプリをローカルで実行します

プロジェクトをインポートして構成したので、Webアプリを初めて実行する準備が整いました。

  1. web-startディレクトリのコンソールで、次のFirebaseCLIコマンドを実行します。
firebase serve --only hosting
  1. コマンドラインに次の応答が表示されます。
✔  hosting: Local server: http://localhost:5000

アプリをローカルで提供するためにFirebaseHostingエミュレーターを使用しています。これで、Webアプリがhttp:// localhost:5000から利用できるようになります。 publicサブディレクトリの下にあるすべてのファイルが提供されます。

  1. ブラウザを使用して、 http:// localhost:5000でアプリを開きます。

FriendlyChatアプリのUIが表示されますが、これは(まだ!)機能していません。

4c23f9475228cef4.png

アプリは現在何もできませんが、あなたの助けを借りてすぐにできます!これまでのところ、UIのレイアウトのみを行っています。

リアルタイムチャットを作成しましょう!

6.Firebaseをインポートして設定します

FirebaseSDKをインポートする

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

npmからFirebaseSDKを取得し、 Webpackを使用してコードをバンドルします。これは、Webpackが不要なコードを削除し、JSバンドルのサイズを小さくして、アプリができるだけ早く読み込まれるようにするためです。このコードラボでは、FirebaseSDKを依存関係として含むweb-start/package.jsonファイルをすでに作成しており、必要な関数をweb-start/src/index.jsの先頭にインポートしています。

package.json

"dependencies": {
  "firebase": "^9.0.0"
}

index.js

import { initializeApp } from 'firebase/app';
import {
  getAuth,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup,
  signOut,
} from 'firebase/auth';
import {
  getFirestore,
  collection,
  addDoc,
  query,
  orderBy,
  limit,
  onSnapshot,
  setDoc,
  updateDoc,
  doc,
  serverTimestamp,
} from 'firebase/firestore';
import {
  getStorage,
  ref,
  uploadBytesResumable,
  getDownloadURL,
} from 'firebase/storage';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getPerformance } from 'firebase/performance';

このコードラボでは、Firebase認証、Cloud Firestore、クラウドストレージ、クラウドメッセージング、パフォーマンスモニタリングを使用するため、すべてのライブラリをインポートします。今後のアプリでは、アプリの読み込み時間を短縮するために、必要なFirebaseの部分のみをインポートするようにしてください。

Firebase SDKをインストールして、Webpackビルドを開始します

アプリのビルドを開始するには、いくつかのコマンドを実行する必要があります。

  1. 新しいターミナルウィンドウを開く
  2. web-startディレクトリにいることを確認してください
  3. npm installを実行して、FirebaseSDKをダウンロードします
  4. npm run startを実行して、Webpackを起動します。 Webpackは、残りのコードラボのコースコードを継続的に再構築します。

Firebaseを設定する

また、Firebase SDKを構成して、使用しているFirebaseプロジェクトを通知する必要があります。

  1. Firebaseコンソールでプロジェクト設定に移動します
  2. [アプリ]カードで、構成オブジェクトが必要なアプリのニックネームを選択します。
  3. FirebaseSDKスニペットペインから[構成]を選択します。
  4. 構成オブジェクトスニペットをコピーして、 web-start/src/firebase-config.jsに追加します。

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

次に、 web-start/src/index.jsの下部に移動し、Firebaseを初期化します。

index.js

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

7.ユーザーサインインを設定します

これで、Firebase SDKがindex.htmlにインポートされて初期化されるため、使用できるようになります。次に、 FirebaseAuthenticationを使用してユーザーサインインを実装します。

Googleログインでユーザーを認証する

アプリでは、ユーザーが[ Googleでサインイン]ボタンをクリックすると、 signInイン機能がトリガーされます。 (すでに設定済みです!)このコードラボでは、FirebaseがGoogleをIDプロバイダーとして使用することを承認します。ポップアップを使用しますが、Firebaseから他のいくつかの方法を利用できます。

  1. web-startディレクトリのサブディレクトリsrc/で、 index.jsを開きます。
  2. 関数signInを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Signs-in Friendly Chat.
async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider);
}

signOutアウト機能は、ユーザーが[サインアウト]ボタンをクリックするとトリガーされます。

  1. src/index.jsファイルに戻ります。
  2. 関数signOutUserを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Signs-out of Friendly Chat.
function signOutUser() {
  // Sign out of Firebase.
  signOut(getAuth());
}

認証状態を追跡する

それに応じてUIを更新するには、ユーザーがサインインしているかサインアウトしているかを確認する方法が必要です。 Firebase Authenticationを使用すると、認証状態が変化するたびにトリガーされる認証状態にオブザーバーを登録できます。

  1. src/index.jsファイルに戻ります。
  2. 関数initFirebaseAuthを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Initialize firebase auth
function initFirebaseAuth() {
  // Listen to auth state changes.
  onAuthStateChanged(getAuth(), authStateObserver);
}

上記のコードは、関数authStateObserverを認証状態オブザーバーとして登録します。認証状態が変化するたびに(ユーザーがサインインまたはサインアウトしたときに)トリガーされます。この時点で、UIを更新して、サインインボタン、サインアウトボタン、サインインしたユーザーのプロフィール写真などを表示または非表示にします。これらのUIパーツはすべてすでに実装されています。

サインインしたユーザーの情報を表示します

サインインしたユーザーのプロフィール写真とユーザー名をアプリのトップバーに表示したいと思います。 Firebaseでは、サインインしたユーザーのデータは常にcurrentUserオブジェクトで利用できます。以前は、ユーザーがサインインしたときにトリガーするようにauthStateObserver関数を設定して、UIがそれに応じて更新されるようにしました。トリガーされると、 getProfilePicUrlgetUserNameが呼び出されます。

  1. src/index.jsファイルに戻ります。
  2. 関数getProfilePicUrlおよびgetUserNameを見つけます。
  3. 両方の関数を次のコードに置き換えます。

index.js

// Returns the signed-in user's profile Pic URL.
function getProfilePicUrl() {
  return getAuth().currentUser.photoURL || '/images/profile_placeholder.png';
}

// Returns the signed-in user's display name.
function getUserName() {
  return getAuth().currentUser.displayName;
}

ユーザーがサインインしていないときにユーザーがメッセージを送信しようとすると、エラーメッセージが表示されます(ただし、試すことはできます)。したがって、ユーザーが実際にサインインしているかどうかを検出する必要があります。

  1. src/index.jsファイルに戻ります。
  2. 関数isUserSignedInを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!getAuth().currentUser;
}

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

  1. アプリがまだ提供されている場合は、ブラウザーでアプリを更新します。それ以外の場合は、コマンドラインでfirebase serve --only hostingを実行して、 http:// localhost:5000からアプリの提供を開始し、ブラウザで開きます。
  2. サインインボタンとGoogleアカウントを使用してアプリにサインインします。 auth/operation-not-allowedというエラーメッセージが表示された場合は、Firebaseコンソールで認証プロバイダーとしてGoogleログインが有効になっていることを確認してください。
  3. サインインすると、プロフィール写真とユーザー名が表示されます。 c7401b3d44d0d78b.png

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

このセクションでは、アプリのUIにデータを入力できるように、CloudFirestoreにデータを書き込みます。これはFirebaseコンソールを使用して手動で実行できますが、基本的なCloudFirestoreの書き込みを示すためにアプリ自体で実行します。

データ・モデル

Cloud Firestoreデータは、コレクション、ドキュメント、フィールド、およびサブコレクションに分割されます。チャットの各メッセージは、 messagesと呼ばれるトップレベルのコレクションにドキュメントとして保存されます。

688d7bc5fb662b57.png

CloudFirestoreにメッセージを追加する

ユーザーが作成したチャットメッセージを保存するには、 CloudFirestoreを使用します。

このセクションでは、ユーザーがデータベースに新しいメッセージを書き込むための機能を追加します。ユーザーが[送信]ボタンをクリックすると、以下のコードスニペットがトリガーされます。メッセージフィールドの内容を含むメッセージオブジェクトを、 messagesコレクションのCloudFirestoreインスタンスに追加します。 add()メソッドは、自動生成されたIDを持つ新しいドキュメントをコレクションに追加します。

  1. src/index.jsファイルに戻ります。
  2. 関数saveMessageを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
  // Add a new message entry to the Firebase database.
  try {
    await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      text: messageText,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });
  }
  catch(error) {
    console.error('Error writing new message to Firebase Database', error);
  }
}

メッセージの送信をテストする

  1. アプリがまだ提供されている場合は、ブラウザーでアプリを更新します。それ以外の場合は、コマンドラインでfirebase serve --only hostingを実行して、 http:// localhost:5000からアプリの提供を開始し、ブラウザで開きます。
  2. サインイン後、「Hey there!」などのメッセージを入力し、[送信]をクリックします。これにより、メッセージがCloudFirestoreに書き込まれます。ただし、データの取得を実装する必要があるため(コードラボの次のセクション) 、実際のWebアプリにはまだデータが表示されません
  3. 新しく追加されたメッセージは、Firebaseコンソールで確認できます。 Firebaseコンソールを開きます。 [ビルド]セクションで[ Firestoreデータベース]をクリックし(またはここをクリックしてプロジェクトを選択します)、新しく追加されたメッセージを含むメッセージコレクションが表示されます。

6812efe7da395692.png

9.メッセージを読む

メッセージを同期する

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

アプリから新しく追加されたメッセージをリッスンするコードを追加します。このコードでは、データに加えられた変更をリッスンするリスナーを登録します。読み込み時に非常に長い履歴が表示されないように、チャットの最後の12個のメッセージのみを表示します。

  1. src/index.jsファイルに戻ります。
  2. 関数loadMessagesを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
  
  // Start listening to the query.
  onSnapshot(recentMessagesQuery, function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                      message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

データベース内のメッセージをリッスンするために、 collection関数を使用して、リッスンするデータが含まれるコレクションを指定することにより、コレクションに対するクエリを作成します。上記のコードでは、 messages内の変更をリッスンしています。コレクション。チャットメッセージが保存される場所です。また、 .limit(12)を使用して最後の12個のメッセージのみをリッスンし、 orderBy('timestamp', 'desc')を使用して日付順にメッセージを並べ替えて、最新の12個のメッセージを取得することで制限を適用しています。

onSnapshot関数は、最初のパラメーターとしてクエリを受け取り、2番目のパラメーターとしてコールバック関数を取ります。クエリに一致するドキュメントに変更があった場合、コールバック関数がトリガーされます。これは、メッセージが削除、変更、または追加された場合に発生する可能性があります。これについて詳しくは、 CloudFirestoreのドキュメントをご覧ください。

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

  1. アプリがまだ提供されている場合は、ブラウザーでアプリを更新します。それ以外の場合は、コマンドラインでfirebase serve --only hostingを実行して、 http:// localhost:5000からアプリの提供を開始し、ブラウザで開きます。
  2. 以前にデータベースに作成したメッセージは、FriendlyChat UIに表示されます(以下を参照)。新しいメッセージを自由に書いてください。それらはすぐに表示されるはずです。
  3. (オプション) Firebaseコンソールの[データベース]セクションで、新しいメッセージを手動で直接削除、変更、または追加してみることができます。変更はすべてUIに反映する必要があります。

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

2168dec79b573d07.png

10.画像を送信する

次に、画像を共有する機能を追加します。

Cloud Firestoreは構造化データの保存に適していますが、CloudStorageはファイルの保存に適しています。 Cloud Storage for Firebaseはファイル/ブロブストレージサービスであり、ユーザーがアプリを使用して共有するすべての画像を保存するために使用します。

画像をクラウドストレージに保存

このコードラボでは、ファイルピッカーダイアログをトリガーするボタンをすでに追加しています。ファイルを選択すると、 saveImageMessage関数が呼び出され、選択したファイルへの参照を取得できます。 saveImageMessage関数は、次のことを実行します。

  1. チャットフィードに「プレースホルダー」チャットメッセージを作成し、画像のアップロード中にユーザーに「読み込み中」のアニメーションが表示されるようにします。
  2. イメージファイルをCloudStorageに次のパスにアップロードします: /<uid>/<messageId>/<file_name>
  3. 画像ファイルの公的に読み取り可能なURLを生成します。
  4. 画像を一時的に読み込む代わりに、新しくアップロードされた画像ファイルのURLでチャットメッセージを更新します。

次に、画像を送信する機能を追加します。

  1. src/index.jsファイルに戻ります。
  2. 関数saveImageMessageを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
async function saveImageMessage(file) {
  try {
    // 1 - We add a message with a loading icon that will get updated with the shared image.
    const messageRef = await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      imageUrl: LOADING_IMAGE_URL,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${getAuth().currentUser.uid}/${messageRef.id}/${file.name}`;
    const newImageRef = ref(getStorage(), filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    });
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

画像の送信をテストする

  1. アプリがまだ提供されている場合は、ブラウザーでアプリを更新します。それ以外の場合は、コマンドラインでfirebase serve --only hostingを実行して、 http:// localhost:5000からアプリの提供を開始し、ブラウザで開きます。
  2. サインインした後、画像アップロードボタンをクリックします13734cb66773e5a3.pngファイルピッカーを使用して画像ファイルを選択します。画像をお探しの場合は、このコーヒーカップの素敵な写真をお気軽にご利用ください。
  3. 選択した画像とともに、アプリのUIに新しいメッセージが表示されます。 3b1284f5144b54f6.png

サインインしていないときに画像を追加しようとすると、画像を追加するにはサインインする必要があることを通知するToast通知が表示されます。

11.通知を表示する

ブラウザ通知のサポートを追加します。アプリは、チャットに新しいメッセージが投稿されたときにユーザーに通知します。 Firebase Cloud Messaging (FCM)は、メッセージと通知を無料で確実に配信できるクロスプラットフォームのメッセージングソリューションです。

FCMサービスワーカーを追加します

Webアプリには、Web通知を受信して​​表示するServiceWorkerが必要です。

  1. web-startディレクトリのsrcディレクトリで、 firebase-messaging-sw.jsます。
  2. そのファイルに次のコンテンツを追加します。

firebase-messaging-sw.js

// Import and configure the Firebase SDK
import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { getFirebaseConfig } from './firebase-config';

const firebaseApp = initializeApp(getFirebaseConfig());
getMessaging(firebaseApp);
console.info('Firebase messaging service worker is set up');

Service Workerは、Firebase Cloud Messaging SDKを読み込んで初期化するだけで、通知の表示を処理します。

FCMデバイストークンを取得する

デバイスまたはブラウザで通知が有効になっている場合は、デバイストークンが提供されます。このデバイストークンは、特定のデバイスまたは特定のブラウザに通知を送信するために使用するものです。

ユーザーがサインインすると、 saveMessagingDeviceToken関数が呼び出されます。ここで、ブラウザからFCMデバイストークンを取得し、CloudFirestoreに保存します。

  1. src/index.jsファイルに戻ります。
  2. 関数saveMessagingDeviceTokenを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Saves the messaging device token to Cloud Firestore.
async function saveMessagingDeviceToken() {
  try {
    const currentToken = await getToken(getMessaging());
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to Cloud Firestore.
      const tokenRef = doc(getFirestore(), 'fcmTokens', currentToken);
      await setDoc(tokenRef, { uid: getAuth().currentUser.uid });

      // This will fire when a message is received while the app is in the foreground.
      // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
      onMessage(getMessaging(), (message) => {
        console.log(
          'New foreground notification from Firebase Messaging!',
          message.notification
        );
      });
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  } catch(error) {
    console.error('Unable to get messaging token.', error);
  };
}

ただし、このコードは最初は機能しません。アプリがデバイストークンを取得できるようにするには、ユーザーがアプリに通知を表示する権限を付与する必要があります(コードラボの次のステップ)。

通知を表示するための権限をリクエストする

ユーザーがアプリに通知を表示する権限をまだ付与していない場合、デバイストークンは付与されません。この場合、 firebase.messaging().requestPermission()メソッドを呼び出します。これにより、この権限を求めるブラウザダイアログが表示されます(サポートされているブラウザの場合)。

8b9d0c66dc36153d.png

  1. src/index.jsファイルに戻ります。
  2. 関数requestNotificationsPermissionsを見つけます。
  3. 関数全体を次のコードに置き換えます。

index.js

// Requests permissions to show notifications.
async function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  const permission = await Notification.requestPermission();
  
  if (permission === 'granted') {
    console.log('Notification permission granted.');
    // Notification permission granted.
    await saveMessagingDeviceToken();
  } else {
    console.log('Unable to get permission to notify.');
  }
}

デバイストークンを取得する

  1. アプリがまだ提供されている場合は、ブラウザーでアプリを更新します。それ以外の場合は、コマンドラインでfirebase serve --only hostingを実行して、 http:// localhost:5000からアプリの提供を開始し、ブラウザで開きます。
  2. サインインすると、通知許可ダイアログが表示されます。 bd3454e6dbfb6723.png
  3. [許可]をクリックします。
  4. ブラウザのJavaScriptコンソールを開きます。次のメッセージが表示されGot FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. デバイストークンをコピーします。コードラボの次の段階で必要になります。

デバイスに通知を送信します

デバイストークンを取得したので、通知を送信できます。

  1. Firebaseコンソールの[クラウドメッセージング]タブを開きます。
  2. 「新規通知」をクリックします
  3. 通知のタイトルと通知テキストを入力します。
  4. 画面右側の「テストメッセージを送信」をクリックします
  5. ブラウザのJavaScriptコンソールからコピーしたデバイストークンを入力し、プラス( "+")記号をクリックします
  6. 「テスト」をクリックします

アプリがフォアグラウンドにある場合は、JavaScriptコンソールに通知が表示されます。

アプリがバックグラウンドにある場合は、次の例のように、ブラウザに通知が表示されます。

de79e8638a45864c.png

12. CloudFirestoreのセキュリティルール

データベースのセキュリティルールを表示する

Cloud Firestoreは、特定のルール言語を使用して、アクセス権、セキュリティ、およびデータ検証を定義します。

このコードラボの冒頭でFirebaseプロジェクトを設定する際、データストアへのアクセスを制限しないように、「テストモード」のデフォルトのセキュリティルールを使用することを選択しました。 Firebaseコンソールの[データベース]セクションの[ルール]タブで、これらのルールを表示および変更できます。

現在、データストアへのアクセスを制限しないデフォルトのルールが表示されます。これは、すべてのユーザーがデータストア内の任意のコレクションの読み取りと書き込みを行えることを意味します。

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

次のルールを使用して、ルールを更新して制限します。

firestore.rules

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

データベースのセキュリティルールを更新する

データベースセキュリティルールを編集するには、Firebaseコンソールで、またはFirebaseCLIを使用してデプロイされたローカルルールファイルから2つの方法があります。

Firebaseコンソールでセキュリティルールを更新するには:

  1. 左側のパネルから[データベース]セクションに移動し、[ルール]タブをクリックします。
  2. すでにコンソールにあるデフォルトのルールを上記のルールに置き換えます。
  3. [公開]をクリックします。

ローカルファイルからセキュリティルールを更新するには:

  1. web-startディレクトリから、 firestore.rulesを開きます。
  2. すでにファイルにあるデフォルトのルールを上記のルールに置き換えます。
  3. web-startディレクトリから、 firebase.jsonを開きます。
  4. 以下に示すように、 firestore.rulesを指すfirestore.rules属性を追加します。 ( hosting属性はすでにファイルに含まれている必要があります。)

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. 次のコマンドを実行して、FirebaseCLIを使用してセキュリティルールをデプロイします。
firebase deploy --only firestore
  1. コマンドラインに次の応答が表示されます。
=== Deploying to 'friendlychat-1234'...

i  deploying firestore
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

13.クラウドストレージのセキュリティルール

CloudStorageのセキュリティルールを表示する

Cloud Storage for Firebaseは、特定のルール言語を使用して、アクセス権、セキュリティ、データ検証を定義します。

このコードラボの冒頭でFirebaseプロジェクトを設定する際に、認証されたユーザーのみがクラウドストレージを使用できるようにするデフォルトのクラウドストレージセキュリティルールを使用することを選択しました。 Firebaseコンソールの[ストレージ]セクションの[ルール]タブで、ルールを表示および変更できます。サインインしているユーザーがストレージバケット内のファイルを読み書きできるようにするデフォルトのルールが表示されます。

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

次のようにルールを更新します。

  • 各ユーザーが自分の特定のフォルダにのみ書き込むことを許可する
  • 誰でもCloudStorageから読み取れるようにする
  • アップロードされたファイルが画像であることを確認してください
  • アップロードできる画像のサイズを最大5MBに制限します

これは、次のルールを使用して実装できます。

storage.rules

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

CloudStorageのセキュリティルールを更新する

ストレージセキュリティルールを編集するには、Firebaseコンソールで、またはFirebaseCLIを使用してデプロイされたローカルルールファイルから2つの方法があります。

Firebaseコンソールでセキュリティルールを更新するには:

  1. 左側のパネルから[ストレージ]セクションに移動し、[ルール]タブをクリックします。
  2. すでにコンソールにあるデフォルトのルールを上記のルールに置き換えます。
  3. [公開]をクリックします。

ローカルファイルからセキュリティルールを更新するには:

  1. web-startディレクトリから、 storage.rulesを開きます。
  2. すでにファイルにあるデフォルトのルールを上記のルールに置き換えます。
  3. web-startディレクトリから、 firebase.jsonを開きます。
  4. 次に示すように、 storage.rulesファイルを指すstorage.rules属性を追加します。 ( hostingおよびdatabase属性はすでにファイルに含まれている必要があります。)

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // Add this!
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. 次のコマンドを実行して、FirebaseCLIを使用してセキュリティルールをデプロイします。
firebase deploy --only storage
  1. コマンドラインに次の応答が表示されます。
=== Deploying to 'friendlychat-1234'...

i  deploying storage
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

14.パフォーマンスデータを収集します

Performance Monitoring SDKを使用して、アプリから実際のパフォーマンスデータを収集し、Firebaseコンソールでそのデータを確認および分析できます。パフォーマンスモニタリングは、アプリのパフォーマンスをいつどこで改善できるかを理解するのに役立ち、その情報を使用してパフォーマンスの問題を修正できます。

Firebase Performance Monitoring JavaScriptSDKと統合するにはさまざまな方法があります。このコードラボでは、ホスティングURLからのパフォーマンスモニタリングを有効にしました。 SDKを有効にする他の方法については、ドキュメントを参照してください。

自動トレース

すでにweb-start/src/index.jsの上部にgetPerformanceをインポートしているので、ユーザーがデプロイされたサイトにアクセスしたときにページの読み込みとネットワーク要求のメトリックを自動的に収集するようにPerformanceMonitoringに指示する1行を追加する必要があります。

  1. web-start/src/index.jsで、既存のTODOの下に次の行を追加して、パフォーマンス監視を初期化します。

index.js

// TODO: Enable Firebase Performance Monitoring.
getPerformance();

最初の入力遅延を測定する(オプション)

ユーザーの操作に応答するブラウザーは、アプリの応答性に関する第一印象をユーザーに与えるため、最初の入力遅延は便利です。

最初の入力遅延は、ユーザーがボタンやハイパーリンクをクリックするなど、ページ上の要素を最初に操作したときに始まります。ブラウザが入力に応答できるようになるとすぐに停止します。つまり、ブラウザはページのコンテンツの読み込みや解析に忙しくありません。

最初の入力遅延を測定する場合は、次のコードを直接含める必要があります。

  1. public/index.htmlを開きます。
  2. 次の行のscriptタグのコメントを解除します。

index.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

最初の入力遅延ポリフィルの詳細については、ドキュメントを参照してください。

パフォーマンスデータの表示

サイトをまだデプロイしていないため(次の手順でデプロイします)、ユーザーがデプロイしたサイトを操作してから30分以内にFirebaseコンソールに表示されるページ読み込みパフォーマンスに関する指標を示すスクリーンショットを次に示します。 :

29389131150f33d7.png

Performance Monitoring SDKをアプリに統合する場合、アプリがパフォーマンスのいくつかの重要な側面の監視を自動的に開始する前に、他のコードを記述する必要はありません。 Webアプリの場合、SDKは、最初のコンテンツの多いペイント、ユーザーがアプリを操作する機能などの側面をログに記録します。

カスタムトレース、指標、属性を設定して、アプリの特定の側面を測定することもできます。カスタムトレースとメトリックおよびカスタム属性の詳細については、ドキュメントにアクセスしてください。

15. FirebaseHostingを使用してアプリをデプロイします

Firebaseは、アセットとウェブアプリを提供するホスティングサービスを提供します。 Firebase CLIを使用して、ファイルをFirebaseHostingにデプロイできます。デプロイする前に、 firebase.jsonファイルでデプロイするローカルファイルを指定する必要があります。このコードラボでは、このコードラボ中にファイルを提供するためにこの手順が必要だったため、これはすでに実行されています。ホスティング設定は、 hosting属性で指定されます。

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

これらの設定は、すべてのファイルを./publicディレクトリ( "public": "./public" )にデプロイすることをCLIに通知します。

  1. コマンドラインがアプリのローカルweb-startディレクトリにアクセスしていることを確認してください。
  2. 次のコマンドを実行して、ファイルをFirebaseプロジェクトにデプロイします。
firebase deploy --except functions
  1. コンソールには次のように表示されます。
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. 独自のFirebaseサブドメインの2つでFirebaseHostingを使用して、グローバルCDNで完全にホストされているウェブアプリにアクセスします。
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

または、コマンドラインでfirebase open hosting:siteを実行することもできます。

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

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

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

Firebaseを使用して、リアルタイムのチャットWebアプリケーションを構築しました。

私たちがカバーしたこと

  • Firebase認証
  • CloudFirestore
  • クラウドストレージ用のFirebaseSDK
  • Firebase Cloud Messaging
  • Firebaseパフォーマンスモニタリング
  • Firebaseホスティング

次のステップ

もっと詳しく知る