Help us understand the problem. What is going on with this article?

Firebase概要まとめ JavaScriptサンプル付き

はじめに

  • 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通知の受け取り方が変わります
  • 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になっています
  • 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のプロジェクト設定方法

プロジェクトの作成

  • プロジェクトを作成します prj1.png
  • プロジェクトにアプリを追加するをクリックしてキー情報など控えておきます
    • この情報は第三者に見られても大丈夫なものです prj4.png

Authentication

  • Authenticationのページでログイン方法の設定をします
  • メール/パスワードを有効にします auth1.png

Firestore

  • データベースの作成をクリックしてロックモードで開始を選択して有効にします
    firestore1.png

  • セキュリティルールを設定します
    firestore2.png

  • これは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

  • 同じようにセキュリティルールを設定します
    storage.png

  • これは/users/{ユーザID}/配下にファイルを読み書きできるのはそのユーザのみというルールを設定しています

service firebase.storage {
  match /b/{bucket}/o {
    match /users/{userId}/{all=**}  {
      allow read, write: if request.auth.uid == userId;
    }
  }
}
  • ルールを設定したら公開ボタンを押して有効にします

Cloud Messaging

  • Project Overviewの右にあるアイコンからプロジェクトの設定ページへ行きます
    fcm1.png

  • 動作確認用にクラウドメッセージングの下にあるWebプッシュ証明書の鍵ペアを生成しておきます
    fcm3.png

  • 表示されている鍵ペアの値を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

おわりに

  • 間違いがあったら編集リクエストをもらえると助かります
  • CodeSandboxのコードはたまにいじると思うのでタイミングによってバグりまくってるかもしれません
  • 時間があったらReact/Vueのサンプルも書いてみたいですね
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away