🔥
Rails7のimportmapでfirebaseuiを使ったOAuthを実装
前提
- Firebase コンソールでアプリの設定済み
環境
$ ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [aarch64-linux]
$ rails -v
Rails 7.0.4
実装
importmapに必要なものを追加する
- firebaseui
$ bin/importmap pin firebaseui
Pinning "firebaseui" to https://ga.jspm.io/npm:firebaseui@6.0.1/dist/esm.js
Pinning "@firebase/app" to https://ga.jspm.io/npm:@firebase/app@0.8.3/dist/esm/index.esm2017.js
Pinning "@firebase/app-compat" to https://ga.jspm.io/npm:@firebase/app-compat@0.1.38/dist/esm/index.esm2017.js
Pinning "@firebase/auth-compat" to https://ga.jspm.io/npm:@firebase/auth-compat@0.2.24/dist/index.esm2017.js
Pinning "@firebase/auth/internal" to https://ga.jspm.io/npm:@firebase/auth@0.20.11/dist/esm2017/internal.js
Pinning "@firebase/component" to https://ga.jspm.io/npm:@firebase/component@0.5.21/dist/esm/index.esm2017.js
Pinning "@firebase/logger" to https://ga.jspm.io/npm:@firebase/logger@0.3.4/dist/esm/index.esm2017.js
Pinning "@firebase/util" to https://ga.jspm.io/npm:@firebase/util@1.7.3/dist/index.esm2017.js
Pinning "dialog-polyfill" to https://ga.jspm.io/npm:dialog-polyfill@0.4.10/dialog-polyfill.js
Pinning "firebase/compat/app" to https://ga.jspm.io/npm:firebase@9.13.0/compat/app/dist/index.esm.js
Pinning "firebase/compat/auth" to https://ga.jspm.io/npm:firebase@9.13.0/compat/auth/dist/index.esm.js
Pinning "idb" to https://ga.jspm.io/npm:idb@7.0.1/build/index.js
Pinning "material-design-lite/src/button/button" to https://ga.jspm.io/npm:material-design-lite@1.3.0/src/button/button.js
Pinning "material-design-lite/src/mdlComponentHandler" to https://ga.jspm.io/npm:material-design-lite@1.3.0/src/mdlComponentHandler.js
Pinning "material-design-lite/src/progress/progress" to https://ga.jspm.io/npm:material-design-lite@1.3.0/src/progress/progress.js
Pinning "material-design-lite/src/spinner/spinner" to https://ga.jspm.io/npm:material-design-lite@1.3.0/src/spinner/spinner.js
Pinning "material-design-lite/src/textfield/textfield" to https://ga.jspm.io/npm:material-design-lite@1.3.0/src/textfield/textfield.js
- @firebase/auth
$ bin/importmap pin @firebase/auth
Pinning "@firebase/auth" to https://ga.jspm.io/npm:@firebase/auth@0.20.11/dist/esm2017/index.js
Pinning "@firebase/app" to https://ga.jspm.io/npm:@firebase/app@0.8.3/dist/esm/index.esm2017.js
Pinning "@firebase/component" to https://ga.jspm.io/npm:@firebase/component@0.5.21/dist/esm/index.esm2017.js
Pinning "@firebase/logger" to https://ga.jspm.io/npm:@firebase/logger@0.3.4/dist/esm/index.esm2017.js
Pinning "@firebase/util" to https://ga.jspm.io/npm:@firebase/util@1.7.3/dist/index.esm2017.js
Pinning "idb" to https://ga.jspm.io/npm:idb@7.0.1/build/index.js
Pinning "tslib" to https://ga.jspm.io/npm:tslib@2.4.1/tslib.es6.js
firebaseuiのスタイルシートを追加する
app/views/layouts/application.html.erb
<%# ... %>
<%= stylesheet_link_tag "application" %>
+ <%= stylesheet_link_tag 'https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.css'%>
<%= javascript_importmap_tags %>
<%# ... %>
stimulusのコントローラーを作成する
初期化関係の処理は公式ドキュメントに書かれている通りに書いていきます。connect()
の中で初期化しましたが、ログアウトやユーザー情報の取得などで再利用すると思うので、適当に共通化したほうがいいと思います。
app/javascript/controllers/login_controller.js
import { Controller } from "@hotwired/stimulus";
import { initializeApp } from "@firebase/app";
import { getAuth, GoogleAuthProvider } from "@firebase/auth";
import * as firebaseui from "firebaseui";
export default class extends Controller {
static targets = ["firebaseuiAuthContainer"];
connect() {
const firebaseConfig = {
apiKey: "[YOUR API KEY]",
authDomain: "[YOUR AUTH DOMAIN]",
projectId: "[YOUR PROJECT ID]",
storageBucket: "[YOUR STORAGE BUCKET]",
messagingSenderId: "[YOUR MESSAGING SENDER ID]",
appId: "[YOUR APP ID]",
};
// firebaseを初期化
initializeApp(firebaseConfig);
// firebase UIを初期化
const auth = getAuth()
const ui = new firebaseui.auth.AuthUI(auth);
// ターゲット「firebaseuiAuthContainer」にログインUIを表示する
ui.start(this.firebaseuiAuthContainer, {
// Google以外のプロパイダでの認証を実装する場合は、他のプロパイダIDを追加する
signInOptions: [GoogleAuthProvider.PROVIDER_ID],
});
}
}
viewを作成する
ログイン機能を実装したいviewに書いていきます。
firebaseuiAuthContainer
の中にログインのUIが表示されます。
<h1>ログイン</h1>
<div data-controller="login">
<div data-login-target="firebaseuiAuthContainer"></div>
</div>
完成
これでfirebaseuiが実装できました。
ログインしたユーザーの情報はonAuthStateChanged
で取得できます。
onAuthStateChanged(auth, (user) => {
if (user) {
console.log(user)
} else {
console.log('未ログイン')
}
});
参考
Discussion