Firebaseとは
Firebaseは、Googleが提供するバックエンドサービスです。いわゆる、BaaS(Backend as a Service)です。
Firebaseは、バックエンドのサービスを担ってくれるので、開発者はアプリケーションの開発に専念することができ、バックエンドで動くサービスを作成、管理する必要はありません。
そのため、素早くアプリケーションをリリースるることができます。
Firebaseは、iOS/AndroidアプリからWebサービスまで幅広く使えます。
Firebaseには、以下のような様々な機能が提供されています。
-
Firebase Authentication
アカウント機能を提供します。メールアドレスとパスワードを使用した一般的な認証の他に、電話番号、匿名認証、TwitterやGoogleアカウント、FacebookなどのSNS認証を使用できます。 -
Realtime Database
オブジェクト型のNoSQLデータベースです。その名の通り、リアルタイムでクライアント全体の情報を同期することができます。データベースの状態を監視して変更があった場合、自動で更新してくれるので、簡単にチャット機能を実装することができます。 -
Cloud Firestore
上記のRealtime Databaseの性能をさらに向上させた、新しいデータベースです。基本的に特別な事情がない限りこちらがおすすめされています。Realtime Databaseと異なり、データをドキュメントで保存します。 -
Cloud Storage
写真や動画など、バイナリーデータを保存するストレージです。 -
Firebase Hosting
HTML、CSS、JavaScriptで構成されたWebアプリケーションなど、静的なページを公開するためのホスティングサービスです。CDNを利用して、コンテンツを高速に配信することができます。 -
Firebase Analytics
アプリの使用状況や、ユーザーの行動などを把握することができます。
500以上のイベントに関するレポートを無制限に生成できます。 -
Firebase Crashlytics
アプリケーションのクラッシュレポートを送信します。
これらの機能はFirebaseの提供するすべての機能のほんの一部にしかすぎません。すべての機能を知りたい場合には、ぜひ公式サイトを確認してみてください。
プロジェクトを作成する
実際にFirebaseのプロジェクトを作成します。Googleアカウントがない場合には先に作成しておく必要があります。
プロジェクトの追加
まずはFirebaseのコンソールへ移動します。
プロジェクトの作成をクリックしましょう。
いくつかの項目を聞かれるので(Google Analticsの使用の有無など)確認したら続行をクリックします。
Firebaseを利用するためのAPIキーを取得しましょう。今回はJavaScript
使用するので、Webアプリケーションのアイコンをクリックします。
JavaSriptのコードが出てくるので、コピペして使用します。
これで基本的なFirebaseの設定は完了です。
Firebase Authentication
実際にFirebase Authenticationを試してみます。
ログイン認証に様々な方法が使えますが、今回はGoogleアカウントを用いた認証を行います。
理由はAPIキー等の入手の必要がなく、とても簡単だからです。(ちなみにTwitter APIはAPIの利用に審査が必要で、審査の申請を出すために利用理由を英語で200文字以上入力する必要があるなどかなり面倒です)
次のような簡単なログインボタンとログアウトボタンだけが表示されるHTMLファイルを用意しました。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
.hide {
display: none;
}
</style>
<title>Document</title>
</head>
<body>
<button id="login">ログイン</button>
<button id="logout" class="hide"></button>
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-auth.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyDPOIelluKaZv8--wAksjl9CZrrOdqYJ40",
authDomain: "awesome-wares-264812.firebaseapp.com",
databaseURL: "https://awesome-wares-264812.firebaseio.com",
projectId: "awesome-wares-264812",
storageBucket: "awesome-wares-264812.appspot.com",
messagingSenderId: "850229978924",
appId: "1:850229978924:web:8c88bd3497c24449766e89"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
<script src="./firebase.js"></script>
</body>
</html>
これをもとにfirebase.js
にコーディングしていきましょう。
Googleプロバイダオブジェクトのインスタンスを作成
Firebase Authentication機能を利用するためには、基本的にはfirebase.auth()
の名前空間で作業をします。
auth用のCDNも忘れずにfirebase-app.js
の後に読み込むようにします。
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-auth.js"></script>
Firebase Auth 自体は多くのサービスプロバイダのOAuthのラッパーとなっています。
Googleアカウントを利用するので、Googleサービスプロバイダを呼び出しましょう。
const provider = new firebase.auth.GoogleAuthProvider()
ログインボタンがクリックされたときに認証を行う
早速認証を行いましょう。ログインボタンが押されたときに認証がされるようにしたいので、ログインボタンのDOMを取得してclick
イベントを購読しましょう。
const loginBtn = document.getElementById('login')
loginBtn.addEventListener('click', () => {
// この中に認証コードを書く
})
認証するさいには、ポップアップウィンドウを表示するか、ログインページにリダイレクトするか選択できます。
-
ポップアップでログイン
signInWithPopup
を呼び出す。 -
ログインページにリダイレクトでログイン
signInWithRedirect
を呼び出す。
今回はポップアップをでログインをしましょう。以下のように呼び出します。
loginBtn.addEventListener('click', () => {
firebase.auth().signInWithPopup(provider).then(result => {
// GoogleプロパイダのOAuthトークンを取得します。
const token = result.credential.accessToken
// ログインしたユーザーの情報を取得します。
const user = result.user
}).catch(function(err) {
console.error(err)
// エラー処理
})
})
ここまでできたら早速ログインボタンをクリックしてみましょう!
認証方法をプロジェクトで有効化する
おっと!エラーが発生してしまいました!コンソールには次のように書いてあります。
この認証方法は使えない、みたいなことが書いてあります。
そうです、うっかりしてましたFirebase Authenticationによる認証を利用するにはコンソールから利用する認証方法を有効化する必要があります。一度コンソールへ戻りましょう。
左のメニューバーから「Authentication」を選択します。
次に、上のタブから「Sign-in method」を選択しましょう。
プロパイダの一覧から「Google」を選択します。
右上にある「有効にする」をオンにします。
さらに、プロジェクトのサポートメールを選択してください。
オンになっていることが確認できたら「保存する」をクリックしましょう。
これで、Googleプロパイダが有効になりました。
もう一度ログインボタンをクリックしてみましょう。
Googleアカウントの選択画面がでてきて、ログインができるはずです。
現在ログインしているユーザーを取得する
通常、ログイン機能が必要なアプリケーションの場合、ユーザーが現在ログインしているかどうか、またログインしているユーザーの情報を知りたいはずです。
そのような場合、Authオブジェクトでオブザーバーを設定します。
firebase.auth().onAuthStateChanged(user => {
if (user) {
// ユーザーがログインしています。
} else {
// ユーザーはログインしていません。
}
})
onAuthStateChanged
はユーザーのログイン状態を監視します。
どうやらログイン情報はIndexedDB
に保存されているようです。
firebase.auth().onAuthStateChangedはどうやってログイン中であることを判定しているんでしょうか?
firebase.auth().currentUser
でも現在ログインしているユーザーが取得できるみたいですが、ログインしているはずなのにcurrentUser
がnull
になることがあるのでおすすめはしません。
ユーザーインスタンスからはユーザーの情報が取得できます。
// uid
user.uid
// 名前
user.displayName
// プロフィール画像
user.photoURL
// メール
user.email
// 認証済みのメールアドレス化
user.emailVerified
// 電話番号
user.phoneNumber
// 匿名認証かどうか
user.isAnonymous
さらに、ユーザープロフィールなど、これ以上のユーザーの情報をもたせたいと思うかもしれません。
そのような場合には、Realtime DB
かCloud Firestore
を利用します。
user
コレクションを作成して、uid
をキーにドキュメントを追加すれば、ログインユーザーのさらなる情報を取得することができます。
ログアウト
ログインしたなら当然ログアウトもしたはずです。
ログアウトはsingOut
を呼び出すだけです。
const logoutBtn = document.getElementById('logout')
logoutBtn.addEventListener('click', () => {
firebase.auth().signOut().then(() => {
// 成功
}).catch(err => {
// 失敗
})
})
以上のように、普通に実装したらまあまあめんどくさい認証機能も簡単に実装することができました。
メールアドレスとパスワードによる認証
Firebase Authenticationによる、Googleアカウントでのログインについて取り上げました。次に、メールアドレスとパスワードによるログインについて取り上げます。
メールアドレスとパスワードによる認証を有効にする。
まずはじめに、前回同様認証を利用するには、その認証方法をコンソール上で有効にする必要があります。メール/パスワード
プロパイダを有効にします。
メール/パスワード
プロパイダを有効にすると、コンソール上でユーザーを追加することができます。
Users
タグをクリックしてユーザーを追加
ボタンをクリックします。
適当なメールアドレスとパスワードを入力して、ユーザーを追加
ボタンをクリックします。
ユーザーの一意となるUID
が付与され、今後このユーザーを利用してログインができるようになります。
ログインフォームを構築する。
予め用意されたUIを利用する
ログインフォームには、Firebase
に予め用意されているUIを利用することができます。
UIを利用するためには追加で以下のCDNを読み込みます。
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
jsファイルに、次のようにUIを初期化するコードを書きます。
ログイン方法には、メールアドレスとパスワードによる認証を指定します。
const ui = new firebaseui.auth.AuthUI(firebase.auth());
ui.start('#firebaseui-auth-container', {
signInOptions: [
firebase.auth.EmailAuthProvider.PROVIDER_ID
],
// Other config options...
})
ログインウィジェットがレンダリングされるDOMを用意します。ui.start
の第一引数に指定されているセレクターに描画されます。(この例では#firebaseui-auth-container
)
最終的なHTMLは次のようになります。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.0/firebase-auth.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
<title>Firebase Auth</title>
</head>
<body>
<div id="firebaseui-auth-container"></div>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyDPOIelluKaZv8--wAksjl9CZrrOdqYJ40",
authDomain: "awesome-wares-264812.firebaseapp.com",
databaseURL: "https://awesome-wares-264812.firebaseio.com",
projectId: "awesome-wares-264812",
storageBucket: "awesome-wares-264812.appspot.com",
messagingSenderId: "850229978924",
appId: "1:850229978924:web:8c88bd3497c24449766e89"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// const provider = new firebase.auth.GoogleAuthProvider()
</script>
<script src="./firebase.js"></script>
</body>
</html>
次のようなログイン画面が表示されました。
さきほど作成したユーザーのメールアドレスを入力してみましょう。
このままパスワードを入力すれば、ログインが完了します。
(ログイン後の処理を書いていないため、とくになにもおきませんが)
また、存在しないユーザーのメールアドレスを入力した場合、そのまま新しいユーザーを作成することができます。
独自のUIコンポーネントを利用する
FirebaseのUIを利用して、簡単にログイン機能を利用することができました。
しかし、独自のUIコンポーネントを利用したいことでしょう。
また、ここからはVue.js
を利用したWebアプリケーションを例にして説明していきます。(すでに作ったものを利用したいので)
Vue CLIアプリ作成
いつもどおりVue CLI
によりVueアプリを作成します。
vue create firebase-app
どうせ使うのでRouter
とVuex
も入れておきましょう。
? Please pick a preset:
default (babel, eslint)
❯ Manually select features
? Check the features needed for your project:
◉ Babel
◯ TypeScript
◯ Progressive Web App (PWA) Support
◉ Router
❯◉ Vuex
◯ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
firebase初期化
FireStoreモジュールをnpmでインストールします。
npm install firebase
src/plugins/firebase.js
ファイルを作成して初期化コードを作成して、export defaut
してアプリケーションでfirebase
を利用できるようにします。
import firebase from 'firebase'
if (!firebase.apps.length) {
firebase.initializeApp(
{
apiKey: process.env.VUE_APP_APIKEY,
authDomain: process.env.VUE_APP_AUTHDOMAIN,
databaseURL: process.env.VUE_APP_DATABASEURL,
projectId: process.env.VUE_APP_PROJECTID,
storageBucket: process.env.VUE_APP_STORAGEBUCKET,
messagingSenderId: process.env.VUE_APP_MESSAGINGSENDERID,
appId: process.env.VUE_APP_APPID,
measurementId: process.env.VUE_APP_MEASUREMENTID,
}
)
}
export default firebase
APIキーはクライアントアプリケーションで利用される前提なので、そのまま書いても構いませんが、なんとなく.env.local
から読み込みます。
VUE_APP_APIKEY=MY_API_KEY
VUE_APP_AUTHDOMAIN=MY_AUTHDOMAIN
VUE_APP_DATABASEURL=MY_DATABASEURL
VUE_APP_PROJECTID=MY_PROJECT_ID
VUE_APP_STORAGEBUCKET=MY_STORAGE
VUE_APP_MESSAGINGSENDERID=MY_MESSAGER
VUE_APP_APPID=MY_APPID
VUE_APP_MEASUREMENTID=MY_MEMEASUREMENTID
Firebase
の認証機能を提供するモジュールをsrc/plugins/auth.js
に書きましょう。
import firebase from '@/plugins/firebase'
export function login (email, password) {
return firebase.auth().signInWithEmailAndPassword(email, password)
}
export function logout() {
return firebase.auth().signOut()
}
export function reAuth(email, password) {
return firebase.auth.EmailAuthProvider.credential(email, password)
}
export function auth () {
return new Promise(resolve => {
firebase.auth().onAuthStateChanged(user => {
resolve(user || false)
})
})
}
メールアドレスとパスワードによるログインを利用するには、firebase.auth().signInWithEmailAndPassword
を利用するので、これをラップした関数をexport
します。
ログアウトは前回と同じく、firebase.auth().signOut
を利用します。これもラップします。
reAuth
関数は後ほど使用します。
ログイン画面
ここからコピペしたログインフォームをちょっといじって利用します。
こんな感じです。
スクリプト部分このようになっています。
なお、バリデーションやエラー処理などは省いています。
<script>
import { validationMixin } from 'vuelidate'
import { required, email } from 'vuelidate/lib/validators'
import { login } from '@/plugins/auth'
export default {
data() {
return {
email: '',
password: '',
redirect: '' // ログイン後にリダイレクトさせたいurl
}
},
// Vuelidateによるバリデーション
mixins: [validationMixin],
validations: {
email: { required, email },
password: { required },
},
methods: {
onSubmit () {
this.$v.$touch(
if (this.$v.$invalid) return
login(this.email, this.password)
.then(() => this.$router.push(this.redirect))
.catch(() => {
// エラー処理をここで行う
})
},
},
}
</script>
はじめにインポートしている
import { validationMixin } from 'vuelidate'
import { required, email } from 'vuelidate/lib/validators'
これらは、Vuelidateという軽量バリデーションライブラリです。ここでは詳細は割愛します。
また、先程作成したauthモジュール
からlogin
関数をインポートしましょう。
import { login } from '@/plugins/auth'
data
プロパティのemail
とpassword
はv-model
によってフォーム入力とバインディングされます。
methods
プロパティのonSubmit
メソッドは、submitイベント
によって呼び出されます。
バリデーションが通過したなら、login
関数を呼び出しましょう。
先程見たとおり、login
関数はfirebase.auth().signInWithEmailAndPassword
のラッパー関数です。
firebase.auth().signInWithEmailAndPassword
は、メールアドレスとパスワードを渡すこによって、ログインをすることができます。
firebase.auth().signInWithEmailAndPassword
は、Promise
を返すので、ログインが成功していることを確認できたなら、ログイン後リダイレクトをさせます。
なんらかの理由でログインに失敗しているのなら、(メールアドレスかパスワードが間違っている、ネットワークエラーなど)エラーをキャッチしてエラー処理を行います。
ログインユーザーの取得
現在ログインしているユーザーは、先週と同じくfirebase.auth().onAuthStateChanged
で取得します。
これも、authモジュール
のauth
関数によってPromise
を返すようにラップしています。
ユーザープロフィールを取得できます。
import { auth } from `@/plugins/auth`
async () => {
const user = await auth()
if (!user) return
user.displayName
user.email
user.emailVarified
user.photoURL
user.uid
}
ユーザーのプロフィールを更新する
updateProfile
メソッドを利用すれば、ユーザーのプロフィールを更新することができます。
import { auth } from `@/plugins/auth`
async () => {
const user = await auth()
if (!user) return
user.updateProfile({
displayName: '新しい名前',
photoURL: 'newPhoto.jpg'
})
}
メールアドレスを更新する
ユーザーのメールアドレスを更新するには、updateEmail
を利用します。
注意しなければいけないところは、メールアドレスやパスワードの更新など、セキュリティ上重要な操作はユーザーが再認証する必要があるところです。
再認証をするためには、まずは新しい認証情報を取得します。
そのためには、firebase.auth.EmailAuthProvider.credential
にemail
とpassword
を渡します。
取得した認証情報をuser
メソッドのreauthenticateWithCredential
にわたすことで、再認証が完了します。
これはauthモジュール
のreAuth
関数でラップしてるので、次のように新しい認証情報を取得できます。
import { reAuth } from '@/src/plugins/auth'
export default {
methods: {
async onSubmit() {
try {
this.loading = true
// 再認証のためのメールアドレスは、ログインユーザーから取得します。
// パスワードはフォーム入力から取得します。
const credential = await reAuth(this.user.email, this.password)
await this.user.reauthenticateWithCredential(credential)
await this.user.updateEmail(this.email)
} catch {
// エラー処理
} finally {
this.loading = false
}
}
}
ユーザーのパスワードを更新する
パスワードの更新も、同じく再認証をする必要があります。
user
メソッドのupdatePassword
を利用します。
まとめ
Firebaseのプロジェクトの初期化から、認証機能の実装までを取り上げました。
思っていたよりも簡単に実装でき、日本語のドキュメントも充実しているので素晴らしいですね。
個人で素早く開発をしたいときにとても役立つと思います。