はじめに
Firebase でチャットアプリを作成するチュートリアル(Firebase web codelab)を試してみました。
チュートリアルでは、以下のことが学べます。
- Cloud Firestore と Cloud Storage のデータ同期
- Firebase Authentication のユーザー認証
- Web アプリケーションのデプロイ
- Firebase Cloud Messaging の通知送信
- Web アプリケーションのパフォーマンスデータ収集
環境
・Firebase 8.2.1
・openSUSE Tumbleweed 20201229
・Virtual Machine:2vCPU, 4GB Memory, 40GB Disk
・VMware(R) Workstation 15 Pro
事前準備
root ユーザー移行
sudo su -
git インストール
zypper install git
npm インストール
zypper install npm
サンプルコードの入手
codelab のリポジトリを複製
git clone https://github.com/firebase/codelab-friendlychat-web
Firebase プロジェクト作成
Firebase にログインして、プロジェクトを作成します。
Firebase Authentication の設定
ウェブアイコン をクリックして、Firebase Web アプリを作成します。
左ペインの「Authentication」➡「Sign-in method」で「Google」をクリックして、有効化します。
Google Cloud Console で OAuth 同意画面を設定します。*1
Cloud Firestore の設定
左ペインの「Cloud FIrestore」から「データベース作成」をクリックして「テストモード」を有効化します。
Firebase CLI インストール
CLI インストール
sudo su -
npm -g install firebase-tools
インストール確認
cd /home/hatkobelab/codelab-friendlychat-web/web-start/ firebase --version
Firebase CLI 承認
firebase login
※CLI をインストールした OS 上で実行する必要があります。それ以外の場合は、localhost に接続できずエラーとなります。本例では、以下のように openSUSE で実行しました。
アプリと Firebase プロジェクトを紐づけ
firebase use --add ? Which project do you want to add? friendlychat-46e4f ? What alias do you want to use for this project? (e.g. staging) default
アプリをローカルで実行
アプリを実行
firebase serve --only hosting
※上述と同様に OS 上で実行します。
ブラウザから http://localhost:5000 に接続
アプリの UI が接続されますが、認証がとおっていないため、まだ機能しません。
ユーザーサインイン設定
チュートリアルでは、Google サインインでユーザー認証するためのコードが用意されているので、対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。
関数:signIn
// Signs-in Friendly Chat. function signIn() { // Sign into Firebase using popup auth & Google as the identity provider. var provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider); }
関数:signOut
// Signs-out of Friendly Chat. function signOut() { // Sign out of Firebase. firebase.auth().signOut(); }
関数:initFirebaseAuth
// Initiate Firebase Auth. function initFirebaseAuth() { // Listen to auth state changes. firebase.auth().onAuthStateChanged(authStateObserver); }
関数:getProfilePicUrl
// Returns the signed-in user's profile pic URL. function getProfilePicUrl() { return firebase.auth().currentUser.photoURL || '/images/profile_placeholder.png'; }
関数:getUserName
// Returns the signed-in user's display name. function getUserName() { return firebase.auth().currentUser.displayName; }
関数:isUserSignedIn
// Returns true if a user is signed-in. function isUserSignedIn() { return !!firebase.auth().currentUser; }
サインインのテストは、上述と同様に OS 上で実行します。
firebase serve --only hosting
以下のように Google でサインインができるようになります。
メッセージの書き込み設定
アプリケーションの UI にデータ入力ができるように Cloud Firestore にデータを書き込みます。ユーザーが作成したメッセージは、Cloud Firestore に保存されます。
チュートリアルでは、ユーザーが「Send」ボタンをクリックすると、データベースに保存するコードが用意されているので、対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。
関数:saveMessage
// Saves a new message to your Cloud Firestore database. function saveMessage(messageText) { // Add a new message entry to the database. return firebase.firestore().collection('messages').add({ name: getUserName(), text: messageText, profilePicUrl: getProfilePicUrl(), timestamp: firebase.firestore.FieldValue.serverTimestamp() }).catch(function(error) { console.error('Error writing new message to database', error); }); }
ブラウザから http://localhost:5000 に接続し「hello」などのメッセージを入力して「Send」ボタンをクリックすると、Firebase コンソールでメッセージを確認できます。
メッセージの読み取り設定
アプリケーションでメッセージを読み取り、表示させます。
データベース内のメッセージが更新された際に、新しいメッセージをアプリケーションに表示させるように対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。
関数:loadMessages
// 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. var query = firebase.firestore() .collection('messages') .orderBy('timestamp', 'desc') .limit(12); // Start listening to the query. query.onSnapshot(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); } }); }); }
画像送信設定
画像を共有する機能を追加します。
Cloud Firestore は、構造化データの保存に適していますが、Cloud Storage はファイルの保存に適しています。
ユーザーがアプリケーションを使用して共有する画像を Cloud Storage に保存するように対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。
関数:saveImageMessage
// Saves a new message containing an image in Firebase. // This first saves the image in Firebase storage. function saveImageMessage(file) { // 1 - We add a message with a loading icon that will get updated with the shared image. firebase.firestore().collection('messages').add({ name: getUserName(), imageUrl: LOADING_IMAGE_URL, profilePicUrl: getProfilePicUrl(), timestamp: firebase.firestore.FieldValue.serverTimestamp() }).then(function(messageRef) { // 2 - Upload the image to Cloud Storage. var filePath = firebase.auth().currentUser.uid + '/' + messageRef.id + '/' + file.name; return firebase.storage().ref(filePath).put(file).then(function(fileSnapshot) { // 3 - Generate a public URL for the file. return fileSnapshot.ref.getDownloadURL().then((url) => { // 4 - Update the chat message placeholder with the image's URL. return messageRef.update({ imageUrl: url, storageUri: fileSnapshot.metadata.fullPath }); }); }); }).catch(function(error) { console.error('There was an error uploading a file to Cloud Storage:', error); }); }
ブラウザから http://localhost:5000 に接続し「hello」などのメッセージを入力して「Send」ボタンをクリックすると、アプリケーションに表示されます。また、画像をアプリケーションにアップロードすることもできます。
パフォーマンスデータ収集
Performance Monitoring SDK を使用して、アプリケーションからパフォーマンスデータを収集し、Firebase コンソールでデータの確認および分析ができます。
自動トレースの設定
アプリケーション利用時に自動的にパフォーマンスデータ監視を行うためには、main.js に以下を追加します。
// TODO: Initialize Firebase Performance Monitoring. firebase.performance();
パフォーマンスデータの表示
Firebase コンソールからパフォーマンスデータを確認できます。通常は、この後の手順で実施するデプロイ後、12時間以内に表示されます。
アプリケーションのデプロイ
Firebase Hosting を使用してアプリケーションを Firebase プロジェクトにデプロイします。
コマンドは以下を使用します。
> cd /home/hatkobelab/codelab-friendlychat-web/web-start/ > firebase deploy --except functions
デプロイ後、Firebase Hosting の URL(以下の2つの Firebase 独自サブドメイン)から、ウェブアプリケーションにアクセスできるようになります。
https://<firebase-projectId>.firebaseapp.com https://<firebase-projectId>.web.app
通知設定
Firebase Cloud Messaging を使用して、ウェブアプリに通知を配信することができます。
送信者 ID 許可
アプリケーション側で、通知を許可する送信 ID を設定する必要があります。 web-start/public/manifest.json の gcm_sender_id で設定します。※固定値で変更できません。
{ "name": "Friendly Chat", "short_name": "Friendly Chat", "start_url": "/index.html", "display": "standalone", "orientation": "portrait", "gcm_sender_id": "103953800507" }
Service Worker の追加
通知をアプリケーションに表示させるために必要な Service Worker を追加します。 web-start/public ディレクトリに irebase-messaging-sw.js という名前のファイルを作成して、以下のコンテンツを追加します。*2
// Import and configure the Firebase SDK // These scripts are made available when the app is served or deployed on Firebase Hosting // If you do not want to serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup importScripts('/__/firebase/8.2.1/firebase-app.js'); importScripts('/__/firebase/8.2.1/firebase-messaging.js'); importScripts('/__/firebase/init.js'); firebase.messaging();
デバイストークンの取得
デバイスまたはブラウザで通知が有効になると、デバイストークンが提供されます。
ユーザーがサインインすると、ブラウザからデバイストークンを取得し、Cloud Firestore に保存するように設定します。ファイルは web-start/public/scripts/main.js です。
// Saves the messaging device token to the datastore. function saveMessagingDeviceToken() { firebase.messaging().getToken().then(function(currentToken) { if (currentToken) { console.log('Got FCM device token:', currentToken); // Saving the Device Token to the datastore. firebase.firestore().collection('fcmTokens').doc(currentToken) .set({uid: firebase.auth().currentUser.uid}); } else { // Need to request permissions to show notifications. requestNotificationsPermissions(); } }).catch(function(error){ console.error('Unable to get messaging token.', error); }); }
通知権限のリクエスト
ユーザーに通知許可を求めるダイアログをブラウザに表示させます。ユーザーで許可していない場合、デバイストークンは提供されません。
// Requests permission to show notifications. function requestNotificationsPermissions() { console.log('Requesting notifications permission...'); firebase.messaging().requestPermission().then(function() { // Notification permission granted. saveMessagingDeviceToken(); }).catch(function(error) { console.error('Unable to get permission to notify.', error); }); }
サインイン後、通知許可ダイアログが表示されます。
「許可」をクリックすると、ブラウザの JavaScript コンソールに次のメッセージが表示されます。
Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
ブラウザに通知を送信
デバイストークンと、サーバーキーを設定し、次の cURL コマンドを実行します。
サーバーキーは、Firebase コンソール から「プロジェクトの概要」➡「プロジェクトを設定」➡「Cloud Messaging」 で確認できます。
curl -H "Content-Type: application/json" \ -H "Authorization: key=YOUR_SERVER_KEY" \ -d '{ "notification": { "title": "New chat message!", "body": "There is a new message in FriendlyChat", "icon": "/images/profile_placeholder.png", "click_action": "http://localhost:5000" }, "to": "YOUR_DEVICE_TOKEN" }' \ https://fcm.googleapis.com/fcm/send
アプリケーションがバックグラウンドにある場合、次のようにブラウザに通知が表示されます。
以上