はじめに
- PoC用にちょっとしたWebアプリをすばやく開発したくFirebaseについて調べ始めたのでまとめていこうと思います
- Webアプリ(JavaScript)で使えないところはあまり詳しく調べていません
- Authentication、Cloud、Firestore、Cloud Storage、Cloud Messagingを使ったサンプルコードを書いてみました
- ついでにHostingの手順も書きました
- Firebaseの設定方法も書いてあるのでこの記事を読めばFirebaseを使った開発を始められると思います
- 主にFirebase公式サイトを読んでまとめているので一通り読まれた方にとっては新しい情報がないかもしれません
Firebaseとは
- BaaS, mBaasと呼ばれるWebアプリやモバイルアプリに必要なバックエンド機能を提供してくれるサービスです
- (mobile) Backend as a Serviceの略
- ログイン、プッシュ通知、DBなどの機能を提供してくれます
- 各機能はプロダクトと呼ばれる単位に分かれており必要な機能だけを選んで利用することができます
対応プラットフォーム(SDK)
- iOS
- Android
- Web(クライアントサイド)
- Unity
- C++
- Admin SDK(Node.js、Java、Python、Go、C#)
- サーバサイド用途です
- 秘密鍵を使って認証します
- GCP内であればサービスアカウントも利用できるようです
JavaScriptサンプルコード
- サンプルコードはCodeSandboxに置いてあります
- https://codesandbox.io/s/m5xzoz6ro9
- Authentication、Cloud Firestore、Cloud Storage、Cloud Messagingが試せます
- Cloud MessagingはファイルをアップロードするとPush通知が飛んできます
- WindowがフォアグランドかバッググランドかによってPush通知の受け取り方が変わります
- Cloud MessagingはファイルをアップロードするとPush通知が飛んできます
- src/_firebase.jsの以下部分を部分を書き換えれば任意のプロジェクトで動かせると思います
- Firebaseのプロジェクトページから「アプリを追加」をクリックするとそのプロジェクトのキー情報などが取得できます
- バグっていたらすみません
src/_firebase.js
var config = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: ""
};
料金プラン
- 制限や上限はありますが無料で全てのプロダクトを利用できます
- サービスの規模に応じて段階的にプランをアップグレードできます
- 詳細は公式ページを参照してください
Sparkプラン
- 無料
Flameプラン
- $25/月
Blazeプラン
- 従量制
Firebaseプロダクトの説明
Authentication
- 認証サービスです
- FirebaseUIというUIも提供しています
- 認証方法は以下になります
- メール/パスワード
- フェデレーションID(Google、Facebook、Twitter、GitHub)
- 電話番号
- 既存認証システムとの統合
- 匿名認証(プッシュ通知などに使えるらしい)
- JWT(JSON Web Token)を利用します
- 認可はCloud Firestoreなどの他プロダクト内でセキュリティルールを設定して行います
Realtime Database
- NoSQLクラウドデータベースです
- オフラインサポートはiOS、Androidのみ
- クエリはシンプルなものしかないようです
- Cloud FirestoreとRealtime Databaseはどちらか一方しか使えません
Cloud Firestore
- NoSQLクラウドデータベースです
- オフラインサポートはiOS、Android、Webとなるようです
- Realtime Databaseよりリッチなクエリを使えます
- オートスケーリングを備えています
- 今後はこちらが主流になるはず
ですが、2018年12月時点ではBetaになっています- 2019年1月末にBetaが終わりGAとなりました!https://firebase.googleblog.com/2019/01/cloud-firestore-in-general-availability.html
- Cloud FirestoreとRealtime Databaseはどちらか一方しか使えません
Hosting
- Webアプリのホスティングサービス
- CDNがついてくるようです
- SSLが提供されます
- 過去のデプロイにロールバックできる機能があります
- カスタムドメインに対応しています
Cloud Functions for Firebase
- FaaS、AWSのLambdaみたいなやつです
- トリガーの種類
- Cloud Firestore
- Realtime Database
- Remote Config
- Firebase Authentication
- Google Analytics for Firebase
- Crashlytics
- Cloud Storage
- Cloud Pub/Sub
- HTTP
- トリガーの種類
- 無料のSparkプランだと外部ネットワークにアクセスできません(外部APIなどを叩けません)
Cloud Storage for Firebase
- クラウドストレージサービス、AWSのS3みたいなやつです
- Firebase SDKで直接アップロード、ダウンロードができます
- セキュリティルールを設定することでファイルの公開、非公開を制御できます
- GCPのサービスと統合されておりGCPのStorageからもアクセスできるようです
ML Kit
- 機械学習サービスです
- 予め用意されたモデルと独自のTensorFlowモデルを利用できます
- 予め用意された以下モデルがあります(一部はクラウドのみでの提供となります)
- テキスト認識(OCR)
- 顔検出
- バーコードスキャン
- 画像のラベル付け
- ロゴ認識
- ランドマーク認識
- 不適切なコンテンツの検出
- 類似画像の検索
- カスタムされたTensorFLowモデルを利用することもできるようです
Cloud Messaging(FCM)
- リモートPush通知です
- Pushの送り方は3パターンあります
- 個々のデバイス
- デバイスのグループ
- 特定トピックの配信登録をしているデバイス
- WebはServiceWorker、Push APIを利用します
- 一部のモダンブラウザでしか利用できません
- iOSのブラウザは現時点ではPush APIに未対応です
In-App Messaging
- Android、iOSのアプリ内Push通知です
Crashlytics
- Android、iOSのクラッシュレポートです
Performance Monitoring
- Android、iOSのパフォーマンスモニタリングです
Test Lab
- Android、iOSのクラウドテスティングです
Google Analytics for Firebase
- GAのモバイルアプリ版です
Predictions
- ユーザの行動ログからクラスタリングしてアプリの挙動を変えられるサービスのようです
- アナリティクスデータに機械学習を適用し、予測された行動に基づいて動的にユーザーグループを作成できるようです
- Remote Configと組み合わせて使うものだと思われます
A/B Testing
- Android、iOSのA/Bテストです
- アプリの見た目、動作、Push通知を切り替えられるようです
- Remote Configと組み合わせて使うものだと思われます
Remote Config
- アプリの見た目、動作の設定を持つことができます
- アプリのアップデートなしに切り替えられます
- Predictions、A/B Testing、FCMと組み合わせて使うものだと思われます
Dynamic Links
- アプリインストールの有無にかかわらず、共通で使えるリンクの提供してくれます
- インストールされていればアプリが開き、そうでなければブラウザが開きます
App Indexing
- Google検索結果にアプリを表示することできるようになります
- アプリをインストールしていればアプリが開く、そうでなければアプリのインストールカードが表示されます
プロダクトとSDKの対応表(2019年2月時点)
プロダクト | Beta | 料金 | iOS | Android | Web | Unity | C++ | Admin |
---|---|---|---|---|---|---|---|---|
Authentication | 無料 | ○ | ○ | ○ | ○ | ○ | ○ | |
Cloud Firestore | 規模に応じて課金 | ○ | ○ | ○ | ○ | |||
Realtime Database | 規模に応じて課金 | ○ | ○ | ○ | ○ | ○ | ○ | |
Hosting | 規模に応じて課金 | ○ | ||||||
Cloud Functions for Firebase | 規模に応じて課金 | ○ | ○ | ○ | ○ | ○ | ○ | |
Cloud Storage for Firebase | 規模に応じて課金 | ○ | ○ | ○ | ○ | ○ | ○ | |
ML Kit | ○ | 規模に応じて課金 | ○ | ○ | ||||
Cloud Messaging | 無料 | ○ | ○ | ○ | ○ | ○ | ○ | |
In-App Messaging | 無料 | ○ | ○ | |||||
Crashlytics | 無料 | ○ | ○ | |||||
Performance Monitoring | 無料 | ○ | ○ | |||||
Test Lab | 規模に応じて課金 | ○ | ○ | |||||
Google Analytics for Firebase | 無料 | ○ | ○ | ○ | ○ | |||
Predictions | ○ | 無料 | ○ | ○ | ○ | ○ | ||
A/B Testing | ○ | 無料 | ○ | ○ | ||||
Remote Config | 無料 | ○ | ○ | ○ | ○ | |||
Dynamic Links | 無料 | ○ | ○ | ○ | ○ | |||
App Indexing | 無料 | ○ | ○ |
Firebaseのプロジェクト設定方法
プロジェクトの作成
Authentication
Firestore
-
これはusersとmessage-tokensというデータのコレクションに対してセキュリティルールを設定しています
- 更新、削除はデータを作成したユーザのみができるとなっています
- データ追加は認証中のユーザのみができるとなっています
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches the 'author_id' field
// of the document
match /users/{user} {
allow read, update, delete: if request.auth.uid == resource.data.author_id;
allow create: if request.auth.uid != null;
}
match /message-tokens/{user} {
allow read, update, delete: if request.auth.uid == resource.data.author_id;
allow create: if request.auth.uid != null;
}
}
}
- ルールを設定したら公開ボタンを押して有効にします
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /users/{userId}/{all=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
- ルールを設定したら公開ボタンを押して有効にします
Cloud Messaging
-
表示されている鍵ペアの値をJavaScriptコードのmessaging.usePublicVapidKeyに渡す必要があります
-
これは公開鍵なのでクライアントコードに書いてあっても大丈夫です(なぜかモザイクかけてしまいました)
- 逆に上にあるサーバーキーは見られたらまずいやつです
src/_messaging.js
messaging.usePublicVapidKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- firebase-messaging-sw.jsのmessagingSenderIdに送信者IDに表示されている値を設定します
manifest.json
firebase.initializeApp({
messagingSenderId: "XXXXXXXXXXXXXXX"
});
- manifest.jsonにも同じようなID gcm_sender_idを設定する必要がありますが、これはFirebase全体で固定の値となるので変更したらだめなようです
manifest.json
{
"gcm_sender_id": "103953800507"
}
- またサーバキーを使ってcurlコマンドでPush通知が送れます
- KEYとTOKENを設定する必要があります
- サンプルコードに含まれるPush通知送信の準備が終わっている必要もあります(ServiceWorkerなど)
curl -X POST -H "Authorization: key=${SERVER_KEY}" -H "Content-Type: application/json" -d '{
"notification": {
"title": "FCM Message",
"body": "This is an FCM Message",
"icon": "/images/icon.png",
"click_action": "https://localshot:1234/"
},
"to": "${TOKEN}"
}' "https://fcm.googleapis.com/fcm/send"
Cloud Function
- ここは黒い画面が必要になります
- npmは入っている前提で以下コマンドを実行します
- 色々聞かれると思いますが作成したプロジェクトを選択して後はデフォルトを選んでいきます
npm install -g firebase-tools
mkdir firebase
cd firebase
firebase login
firebase init functions
- 以下のようなコードを書きます
- Cloudストレージのファイル作成をトリガーとして起動
- FirestoreからPushメッセージのデバイストークンを取得(トークンはクライアント側からFirestoreに登録してある前提)
- デバイスに向けてPush通知を送信
vi functions/index.js
functions/index.js
const functions = require('firebase-functions');
function sendMessage(admin, registrationToken) {
// See documentation on defining a message payload.
var message = {
"notification": {
"title": "FCM Message",
"body": "This is an FCM Message"
},
"token": registrationToken
};
console.log(message);
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
return true;
})
.catch((error) => {
console.log('Error sending message:', error);
return false;
});
}
exports.sendPushNotification = functions.storage.object().onFinalize((object) => {
console.log(object);
console.log(object["name"]);
const userId = object["name"].split("/")[1];
const admin = require('firebase-admin');
const functions = require('firebase-functions');
if (!admin.apps.length) {
admin.initializeApp(functions.config().firebase);
}
var db = admin.firestore();
db.collection('message-tokens').doc(userId).get()
.then(doc => {
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('Document data:', doc.data());
sendMessage(admin, doc.data()['message_token']);
}
return true;
})
.catch(err => {
console.log('Error getting document', err);
return false;
});
return 0; // See This Link: https://stackoverflow.com/questions/47128440/google-firebase-errorfunction-returned-undefined-expected-promise-or-value?rq=1
});
- 書き終わったらデプロイを行います
firebase deploy
- 以上でFirebaseのプロジェクト設定は終わりです
Hosting
- 既にCodeSandboxでは動くようになっていたのですが ついでHostingの手順も試してみました
- CodeSanxboxからプロジェクトファイルをDLして展開したところからの手順になります
cd firebase-example
firebase init
# Hostingを選択
# 作成したプロジェクトを選択
# distを入力
# あとはデフォルトでOK
npm run build
cp firebase-messaging-sw.js manifest.json dist # Pushに必要ファイルをコピー
firebase deploy
- https://xxxxxxxxxx.firebaseapp.com/ のようなURLでFirebaseのホスティングしたページにアクセスできるようになります
おわりに
- 間違いがあったら編集リクエストをもらえると助かります
- CodeSandboxのコードはたまにいじると思うのでタイミングによってバグりまくってるかもしれません
- 時間があったらReact/Vueのサンプルも書いてみたいですね