はじめに
前回:環境構築
GitHubリポジトリ
準備中
用いる省略名称
RTDB: Realtime Database
操作するファイル
- public
- index.js
- src
- mixins
- databaseOps.js
- router
- index.js
- views
- Authentication.vue (新規ファイル)
- App.vue
- mixins
public/index.js
Vuetify用のfont, material-design-iconを追加。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- update the version number as needed -->
<script src="/__/firebase/8.3.1/firebase-app.js"></script>
<!-- include only the Firebase features as you need -->
<script src="/__/firebase/8.3.1/firebase-auth.js"></script>
<script src="/__/firebase/8.3.1/firebase-database.js"></script>
<script src="/__/firebase/8.3.1/firebase-functions.js"></script>
<!--
initialize the SDK after all desired features are loaded, set useEmulator to false
to avoid connecting the SDK to running emulators.
-->
<script src="/__/firebase/init.js?useEmulator=true"></script>
<script src="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css" />
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
src/mixins/databaseOps.js
- Firebase RTDB関連のfunctionを格納します
- mixinは複数のcomponentで共通するメソッドの格納する目的で用います
-
Vue.prototype.$userId
にユーザーIDを格納して、どのcomponentからも参照できるようにします。
import Vue from 'vue'
export default {
methods: {
// User Credentials
addUserCredentials(data) {
firebase.database().ref('userCredentials/'+this.$userId).set(data);
},
// User Preferences
initUserPreferences() {
var data = {
'notifyAtLinkOpen': false,
'notifyNotLostItem': true,
'whereToNotify': 'email'
};
firebase.database().ref('userPreferences/'+this.$userId).set(data);
},
setUserPreferences(data) {
firebase.database().ref('userPreferences/'+this.$userId).set(data);
},
}
}
src/views/Authentication.vue
src/views
内に新しくAuthentication.vue
を作ります。ログイン・新規登録画面のHTMLです。
-
ログイン・新規登録画面画面
-
loader
はログイン・新規登録画面のdiv要素がロード中に"Loading..."と表示するdiv要素です。 -
firebaseui-auth-container
はログイン・新規登録画面のdiv要素です。
-
-
loginScreen
- mounted
-
mounted
は要素がDOMに追加されたときに呼ばれます。
-
- uiconfig
-
EmailAuthProvider
: メールアドレスとパスワードによるログインを行います。
-
- callbacks
-
signInSuccessWithAuthResult
- サインインに成功したときに呼ばれます。
- サインイン結果から
uid
、displayName
、email
を得ることができます。
- サインイン結果から
- 新規登録の時には
addUser
を呼び、RTDBにユーザーを登録します。
- サインインに成功したときに呼ばれます。
-
uiShown
- UIがロードされたときに呼ばれます。今回はロードが終了したため、
loader
の表示を消します。
- UIがロードされたときに呼ばれます。今回はロードが終了したため、
-
- mounted
-
addUser
- ユーザーを追加し、
userPreferences
を初期設定します。 - Firebase AuthのユーザーID(userId) を
Vue.prototype.$userId
に格納し、他のcomponentから参照できるようにします。
- ユーザーを追加し、
<template>
<!-- authentication -->
<div id="userAuthentication" style="display:block">
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
</div>
</template>
<script>
import Vue from 'vue'
import DatabaseOps from '@/mixins/DatabaseOps'
export default {
name: "Authentication",
mounted () {
this.loginScreen();
},
methods: {
// I wanted to include this in a javascript file, but vue router cannot be called outside /src
loginScreen (){
// FirebaseUI config.
var uiConfig = {
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
//firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
],
callbacks: {
signInSuccessWithAuthResult: (authResult, redirectUrl) => {
Vue.prototype.$userId = authResult.user.uid;
if (authResult.additionalUserInfo.isNewUser){ // if new user, register to database
this.addUser(authResult.user.displayName, authResult.user.email)
}
document.getElementById('userAuthentication').style.display = 'none';
this.$router.push("/MainMenu"); // TBD: router does not work
return false;
},
uiShown: () => {
document.getElementById('loader').style.display = 'none';
},
},
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
},
addUser(userName, email){
var data = {
'email': email,
'name': userName
};
this.addUserCredentials(data);
this.initUserPreferences();
},
},
data: () => ({
//
}),
mixins: [DatabaseOps]
};
</script>
src/router/index.js
新しく追加したAuthentication.vue
のページの情報を追加します。
また、アクセス時には認証画面へのリダイレクトをするように設定します。
参考リンク: https://qiita.com/sin_tanaka/items/ea149a33bd9e4b388241
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [
{
path: "*",
redirect: "/"
},
{
path: "/",
name: "Authentication",
component: () =>
import("@/views/Authentication.vue"),
},
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
router.beforeEach((to, from, next) => {
let requiresAuth = to.matched.some(record => record.meta.requiresAuth)
let currentUser = firebase.auth().currentUser
if (requiresAuth) { // if this page requires auth, redirect to auth page
if (!currentUser) {
next({
path: '/',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // this is required
}
})
export default router;
src/App.vue
Authentication.vue
の設定を追加します。
<template>
<v-app>
<v-main>
<Authentication />
</v-main>
</v-app>
</template>
<script>
//import HelloWorld from "./components/HelloWorld";
import Authentication from "./views/Authentication";
export default {
name: "App",
components: {
Authentication,
},
data: () => ({
//
}),
};
</script>
Build
- ビルドし、動作をテストします。動作のテストにはFirebase Emulatorが必要であるため、起動します。
npm run build
firebase emulators:start
-
dist/index.html
をブラウザで閲覧し下の画像のような画面が出ることを確認します。 -
アカウント作成実行後、AuthとTRDBに正常にアカウント登録の処理がされていることを確認します。
- Firebase Authentication Emulator
- http://localhost:4000/auth にアクセス
- 登録したメールアドレス、名前のアカウントが追加されていることを確認する。
- Firebase RTDB Emulator
- http://localhost:4000/database/{データベース名}/data にアクセス
- 以下のjsonファイルが生成されていることを確認する。
- Firebase Authentication Emulator
http://127.0.0.1:9000/?ns=[データベース名]: {
userCredentials: {
[Firebase AuthのUID]: {
email: "[Email]"
name: "[名前]"
}
},
userPreferences: {
[Firebase AuthのUID]: {
notifyAtLinkOpen: false,
notifyNotLostItem: true,
whereToNotify: "email"
}
}
}
次回
ユーザー設定確認・変更画面