Googleから提供されている、Firebaseでチャットアプリを作成するチュートリアルを試してみたのでメモ。
サンプルファイルの取得
Githubリポジトリからサンプルコードを取得します。
色々ファイルが入っていますが、今回は「web-start」フォルダ内を使用します。
Firebaseプロジェクトの作成
Firebaseのサイトにアクセスして、使ってみるをクリックします。
Googleアカウントにログインしていない場合はログインします。
以下のようなページが表示されるので、プロジェクトを作成をクリックします。
プロジェクト名を追加して、規約の同意にチェックを入れて続行をクリックします。
Google アナリティクスを有効にするかを選択します。
今回は簡単に試したいだけなので、有効にしないで続行をクリックします。
これでプロジェクトの作成が完了しました。
Firebaseプロジェクトの設定
アプリをプロジェクトに追加します。
上部の「>」をクリックします。
アプリのニックネームを入力して、「このアプリのFirebase Hostingも設定します。」にチェックを入れて、アプリを登録をクリックします。
Firebase SDKの追加の指示が表示されますが、今回はチュートリアルのhtmlファイルにすでに記述されていますので飛ばします。
Firebase CLIのインストールとFirebase Hostingへのデプロイは後ほどするので一旦飛ばします。
一通り完了して、コンソール画面に戻りました。
次にGoogleアカウントでアプリにログインできるようにします。
左メニューの開発 > Authentication を選択します。
ログイン方法のタブをクリックします。
プロバイダの一覧からGoogleを選択します。
有効にして、プロジェクトの公開名とサポートメールを設定して保存します。
これでGoogleアカウントでアプリにログインする設定が完了しました。
次にチャットのメッセージを保存するCloud Firestoreを有効にします。
開発 > Database をクリックします。
データベースの作成をクリックします。
セキュリティ保護ルールとロケーションを設定します。
セキュリティは今回動作検証的に使うだけなので「テストモードで開始」を選択、ロケーションは「asia-northeast1」を選択しました。
これでデータベースが作成できました。
この後チュートリアルだと画像の保存用にCloud Storageを有効にしていますが、今回は省略します。
Firebase CLIをインストール
コマンドプロンプトで下記を実行して、Firebase CLIをインストールします。
npm -g install firebase-tools
正しくインストールされたか確認します。
バージョン情報が表示されたらOKです。
firebase --version
次にFirebaseにログインします。
firebase login
エラーレポートの送信を許可するかを聞かれるので、yかnで返答してください。
その後、Firebase CLI がGoogleアカウントへのアクセスをリクエストするので、許可します。
許可すると以下のようなログイン成功画面が表示されます。
これでログイン完了しました。
プロジェクトディレクトリ(web-startのディレクトリ)に移動します。
cd プロジェクトディレクトリ
ローカルのアプリをFirebaseプロジェクトに関連付けします。
firebase use --add
プロジェクトIDとエイリアスを聞かれるので、先ほど作成したプロジェクトのIDを選択して、エイリアスはdefaultにします。
これで一通り準備が完了しましたので、ローカルでアプリを実行してみます。
以下のコマンドを実行します。
firebase serve --only hosting
ブラウザでhttp://localhost:5000を開くと、以下のようにアプリ画面を開くことができました。
この時点ではアプリ用のコードを追加していないので、アプリとしてはまだ機能していません。
Firebaseのインポートと構成
まずFirebase SDKをインポートするのですが、チュートリアルには既に読み込みコードが入っているので飛ばしてOKです。
web-start/public/index.htmlを見ると、下記ファイルの読み込みが入っているかと思います。
<script src="/__/firebase/6.4.0/firebase-app.js"></script> <script src="/__/firebase/6.4.0/firebase-auth.js"></script> <script src="/__/firebase/6.4.0/firebase-storage.js"></script> <script src="/__/firebase/6.4.0/firebase-messaging.js"></script> <script src="/__/firebase/6.4.0/firebase-firestore.js"></script> <script src="/__/firebase/6.4.0/firebase-performance.js"></script> <script src="/__/firebase/init.js"></script>
最後の行のinit.jsはFirebase SDKを設定するファイルになります。
ログインの設定
Googleアカウントでログインできるように設定してみます。
「Sign in with Google」をクリックするとsignIn関数が実行されるようになっているので、この関数の設定を行います。
web-start/public/scripts/main.js 内に空のsignIn関数があるので下記を記述します。
function signIn() { var provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider); }
次にログアウトの設定ですが、「Sign out」をクリックするとsignOut関数が実行されるようになっているので、同様に設定します。
function signOut() { firebase.auth().signOut(); }
ログイン状態に応じてUIを更新する必要があるので、initFirebaseAuth関数で以下のように設定します。
function initFirebaseAuth() { firebase.auth().onAuthStateChanged(authStateObserver); }
ログイン状態が変更する毎に、authStateObserver関数を実行するようにしています。
authStateObserver関数は、main.js内に既に用意されている関数です。
プロフィール画像のURLを取得する関数(getProfilePicUrl)とユーザー名を取得する関数(getUserName)を用意します。
これは上記のauthStateObserver関数内で使用されていて、ログイン時にユーザーの情報を表示するようになります。
function getProfilePicUrl() { return firebase.auth().currentUser.photoURL || '/images/profile_placeholder.png'; } function getUserName() { return firebase.auth().currentUser.displayName; }
ユーザーがログインしているかを判別する関数(isUserSignedIn)を用意します。
これは未ログイン時にメッセージを送信しようとした際、エラーを表示するために使用されます。
function isUserSignedIn() { return !!firebase.auth().currentUser; }
これでログイン周りの実装が完了しましたので、ログインのテストをしてみます。
画面右上の「Sign in with Google」をクリックして、Googleアカウントでログインしてみます。
きちんとログイン情報が表示されればOKです。
メッセージの送信
メッセージを実際に送信して、アプリ上に表示されるようにしてみます。
まずはアプリで送信したメッセージをCloud Firestoreに追加してみます。
SENDをクリックするとsaveMessage関数が実行されるので、以下のように記述します。
function saveMessage(messageText) { 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); }); }
これで送信したメッセージがCloud Firestoreに追加されるようになりましたが、まだアプリ上からは確認できません。
送信できているか確認する場合、開発 > Database から確認できます。
送信したメッセージが入っていることが確認できました。
次にメッセージを同期して、アプリ上にも表示されるようにしてみます。
loadMessages関数を以下のように記述します。
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のセキュリティルール
現在データストアへのアクセスを制限しないようになっているので、このルールを変更します。
開発 > Database のルールタブを選択します。
以下のように変更します。
// 変更前 service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write; } } } // 変更後 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; } } }
変更後公開します。
これでCloud Firestoreへのアクセスに制限をかけることができました。
アプリのデプロイ
最後にFirebase CLIを使って、アプリをデプロイします。
firebase.jsonでデプロイするファイルの指定が必要ですが、今回はチュートリアルそのままなので設定不要です。
以下コマンドを実行して、Firebaseプロジェクトにデプロイします。
firebase deploy --except functions
しばらく待って、「Deploy complete」と表示されたらOKです。
https://【プロジェクトID】.web.app のURLでアプリにアクセスできるようになりました。
【参考サイト】
コメントが承認されるまで時間がかかります。