【2024年3月更新】 firebase + nuxt3のwebアプリ開発手順③
更新履歴
2024年3月 内容更新
記事①と②に合わせて書き方を更新しました
2023年10月 ユーザープロフィールはどこに書くかを作成
2023年7月 plugins/firebase.tsで、provideを返す書き方に変更。
2023年3月 ログイン時と非ログイン時のルーティングを作成
2023年2月 導入手順を作成
全体像
- Nuxt3アプリ作成〜firebaseデプロイ
- 各種スタイル用フレームワーク、ライブラリの導入
- ログイン機能の実装
- firestoreを使ったデータの読み取り、書き込み、更新
設計思想
ここからfirebase authやfirebase storeなどfirebaseの機能をどんどん導入していきます。
作り始める前に、最終的にどのような形になっているのか目標を理解しましょう。
plugins/firebase.ts
クリックで展開
import { initializeApp } from "firebase/app";
// import { getAnalytics } from "firebase/analytics";
import { getAuth } from "firebase/auth";
export default defineNuxtPlugin(() => {
const firebaseConfig = {
apiKey: "****",
authDomain: "***",
projectId: "***",
storageBucket: "***",
messagingSenderId: "***",
appId: "***",
measurementId: "***"
};
initializeApp(firebaseConfig);
return {
provide: {
auth:getAuth(),
}
}
})
-
firebaseではアプリ立ち上げ時に一度だけ、firebase認証(初期化)をする必要があります。
initializeApp(firebaseConfig);
-
Nuxt3ではpluginsフォルダに記載したプログラムが、立ち上げ時に一度だけ実行されるので、ここにfirebase認証(初期化処理)を書いてやりましょう。
-
私流のやり方ですが、provideをreturnしています。これはNuxt3のやり方で、pluginsでprovideで返したプロパティはページやコンポーネントで$で使うことができるからです。
const {$auth, $db} = useNuxtApp()
middleware/auth.global.ts
クリックで展開
import {getAuth, onAuthStateChanged} from '@firebase/auth'
export default defineNuxtRouteMiddleware( async(to,from) => {
if (!process.server) {
const checkAuthState = new Promise((resolve, reject) => {
onAuthStateChanged(getAuth(), async user => {
if (user) {
resolve(user)
} else {
reject()
}
})
})
try {
const user = await checkAuthState
console.log('ログインしています')
} catch (err) {
console.log('ログインしていません!')
// 例 ログインしていなくてもトップページとauthページは見れるが、それ以外のページではauthページにリダイレクトさせる
if(to.path==="/" || to.path.startsWith('/auth')){
return
}else{
return await navigateTo('/auth')
}
}
}
})
- ログイン有無によるルーティング(例えばログインしていない状態でプロフィール編集画面を開こうとすると、ログインページに飛ばす)を設定するにはmiddlewareを使います。
導入手順
Authenticationを有効化
firebaseコンソールで有効化してください。
(普通はパスワード認証とGoogle認証を有効化しとけば十分でしょう。イーロンの暴挙を見るにX(twitter)はやらないほうが良いかも)
firebase toolsの導入
plugins/firebase.tsでインポートするfirebase/app
とfirebase/auth
を利用するために、firebase toolを導入します
$ npm install firebase
plugins/firebase.tsの作成
- apiKeyなどをベタ書きするのは良くないですが、ひとまず動作確認はこれでやります
import { initializeApp } from "firebase/app";
// import { getAnalytics } from "firebase/analytics"; 必要に応じて有効化
export default defineNuxtPlugin( () => {
const firebaseConfig = {
apiKey: "***************",
authDomain: "**************",
databaseURL: "**************",
projectId: "**************",
storageBucket: "**************",
messagingSenderId: "**************",
appId: "**************",
measurementId: "**************"
};
initializeApp(firebaseConfig)
return {
provide: {
auth:getAuth(),
}
}
})
middlewareにログイン時and非ログイン時の処理を実装
基本は冒頭の書き方で良いでしょう。
例えばユーザー情報でauthに収められない情報(課金ユーザーであるか、所属している会社など)がある場合は、それらの情報をfirebase cloudstoreのusersに入れていることがあると思います。
そういった情報はuseStateに'currentUser'を作って格納しておくと何かと便利です。
以下のように書くことで、ログイン中ユーザーの情報をstoreから引っ張ってくる動作を「ログイン時の一度だけ」にすることができます。
try {
const user = await checkAuthState
console.log('ログインしています')
const {$db} = useNuxtApp()
const userRef = doc($db,'users',user.uid)
const userSnap = await getDoc(userRef)
if(userSnap.exists()){
useState('currentUser').value = userSnap.data()
}
} catch (err) {
console.log('ログインしていません!')
}
RuntimeConfigを使ってキーを隠す
.envファイルに以下のように書きます。
- NUXT_PUBLICを冒頭につける
- 全て大文字
NUXT_PUBLIC_FB_API_KEY=****
NUXT_PUBLIC_FB_AUTH_DOMAIN=****
NUXT_PUBLIC_FB_PROJECT_ID =****
NUXT_PUBLIC_FB_STORAGE_BUCKET=****
NUXT_PUBLIC_FB_MESSAGING_SENDER_ID=****
NUXT_PUBLIC_FB_APP_ID=****
NUXT_PUBLIC_FB_MEASUREMENT_ID=****
次にnuxt.config.tsにruntimeConfigとして環境変数を設定します。
上記でNUXT_PUBLICとつけたので、runtimeconfig.publicで環境変数を使用できます
export default defineNuxtConfig({
・・・
runtimeConfig:{
public:{
googleMapsApiKey:process.env.NUXT_PUBLIC_GOOGLE_MAPS_API_KEY,
resasApiKey:process.env.NUXT_PUBLIC_RESAS_API_KEY,
apiKey: process.env.NUXT_PUBLIC_FB_API_KEY,
authDomain: process.env.NUXT_PUBLIC_FB_AUTH_DOMAIN,
projectId: process.env.NUXT_PUBLIC_FB_PROJECT_ID,
storageBucket: process.env.NUXT_PUBLIC_FB_STORAGE_BUCKET,
messagingSenderId: process.env.NUXT_PUBLIC_FB_MESSAGING_SENDER_ID,
appId: process.env.NUXT_PUBLIC_FB_APP_ID,
measurementId: process.env.NUXT_PUBLIC_FB_MEASUREMENT_ID
}
}
}
最後にplugins/firebase.tsで環境変数の呼び出しです。
useRuntimeConfig()で環境変数呼び出しします。
・・・
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
const firebaseConfig = {
apiKey: config.public.apiKey,
authDomain: config.public.authDomain,
projectId: config.public.projectId,
storageBucket: config.public.storageBucket,
messagingSenderId: config.public.messagingSenderId,
appId: config.public.appId,
measurementId: config.public.measurementId
};
// 以下略
})
Discussion