這是第一次用firebase
,記錄一下坑坑點點的過程。
./plugins/firebase.ts
,這樣處理是暫時的,不可能把這些keys放在專案裡,然後推到github歡迎光臨給大家看XD,後面會提我會怎麼整合進CI處理這部分:// ./plugins/firebase.ts
const firebaseConfig = {
apiKey: "XXX",
authDomain: "XXX.firebaseapp.com",
projectId: "XXX",
storageBucket: "XXX.appspot.com",
messagingSenderId: "XXX",
appId: "XXX",
measurementId: "XXX"
};
新增專案到這邊告一個段落。
getAuth
, signInWithEmailAndPassword
, createUserWithEmailAndPassword
, signOut
,// ./plugins/firebase.ts
import { initializeApp } from 'firebase/app';
import { getAuth, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut } from 'firebase/auth';
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "XXX",
authDomain: "XXX.firebaseapp.com",
projectId: "XXX",
storageBucket: "XXX.appspot.com",
messagingSenderId: "XXX",
appId: "XXX",
measurementId: "XXX"
};
export default defineNuxtPlugin(nuxtApp => {
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
nuxtApp.provide('auth', auth);
nuxtApp.provide('signInWithEmailAndPassword', signInWithEmailAndPassword);
nuxtApp.provide('createUserWithEmailAndPassword', createUserWithEmailAndPassword);
nuxtApp.provide('signOut', signOut);
});
到./pages/login.vue
裡,把登入寫好:
// ./pages/login.vue
<script setup lang="ts">
const router = useRouter();
const email: Ref<string> = ref('ecithome2024@test.com');
const password: Ref<string> = ref('aaaa123');
const status = ref({ message: '', type: '' });
const { $auth, $signInWithEmailAndPassword } = useNuxtApp();
const login = async () => {
console.log(`login`);
try {
await $signInWithEmailAndPassword($auth, email.value, password.value);
status.value = { message: '登入成功!', type: 'success' };
// 使用 useRouter 導航
useRouter().push('/'); // 登入後重定向到首頁
} catch (error) {
status.value = { message: '登入失敗!請檢查您的憑證。', type: 'error' };
}
};
// 登入頁不需要layout
definePageMeta({
layout: false
})
</script>
<template>
<div>
<form @submit.prevent="login">
<input type="email" v-model="email" placeholder="Email">
<input type="password" v-model="password" placeholder="Password">
<button type="submit">Login</button>
<NuxtLink to="/registration">還不是會員?</NuxtLink>
<p>{{status.type}} {{status.message}}</p>
</form>
</div>
</template>
<style scoped>
</style>
接著是註冊,原本的設計是除了firebase Authentication這邊要求的email及password欄位以外,另外還要提供名字、電話、地址,不過這部分我想存在firebase realtime database,我不想把登入註冊這一篇用得太複雜,所以這邊單純把firebase Authentication串好就好,等到會員頁再回來補這一塊。
註冊跟登入很像,差別是這邊使用$createUserWithEmailAndPassword
:
// ./pages/registration.vue
<script setup lang="ts">
const router = useRouter();
const { $auth, $createUserWithEmailAndPassword } = useNuxtApp();
const email: Ref<string> = ref('ecithome2024@test.com');
const password: Ref<string> = ref('aaaa123');
const status = ref({ message: '', type: '' });
const regis = async () => {
console.log(`regis`);
try {
await $createUserWithEmailAndPassword($auth, email.value, password.value)
status.value = { message: '註冊成功!', type: 'success' };
useRouter().push('/');
} catch (error) {
console.log(error)
status.value = { message: `${error.message}`, type: 'error' };
}
};
definePageMeta({
layout: false
});
</script>
<template>
<div>
<form @submit.prevent="regis">
<input type="email" v-model="email" placeholder="Email">
<input type="password" v-model="password" placeholder="Password">
<button type="submit">註冊</button>
<NuxtLink to="/login">已經是會員?</NuxtLink>
<p>{{status.type}} {{status.message}}</p>
</form>
</div>
</template>
<style scoped>
</style>
截圖一下失敗case:
功能的部分到上面已經是差不多了,不過像前面提到的,那些firebase的keys得找個安全的地方放,所以會放在被gitignore的.env
裡,環境規劃是這樣的:
先處理local端,首先將firebase的keys先提出,放入專案根目錄的.env
:
FIREBASE_API_KEY="xxx"
FIREBASE_AUTH_DOMAIN="xxx"
FIREBASE_PROJECT_ID="xxx"
FIREBASE_STORAGE_BUCKET="xxx"
FIREBASE_MESSAGING_SENDER_ID="xxx"
FIREBASE_APP_ID="xxx"
FIREBASE_MEASUREMENT_ID="xxx"
接著到nuxt.config.js
設置runtimeConfig
:
export default defineNuxtConfig({
...
runtimeConfig: {
public: {
firebase: {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
measurementId: process.env.FIREBASE_MEASUREMENT_ID,
}
}
},
...
})
最後修改一下firebase
的plugin./plugins/firebase.ts
,將哈扣改成環境變數:
...
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
export default defineNuxtPlugin(nuxtApp => {
const config = useRuntimeConfig();
const firebaseConfig = {
apiKey: config.public.firebase.apiKey,
authDomain: config.public.firebase.authDomain,
projectId: config.public.firebase.projectId,
storageBucket: config.public.firebase.storageBucket,
messagingSenderId: config.public.firebase.messagingSenderId,
appId: config.public.firebase.appId,
measurementId: config.public.firebase.measurementId
};
...
});
再跑一下測試,沒毛病就完成了!
知道我的SideProject30教學成分不居多(什麼文法XD)可能主題也不這麼吸引人(就是百年不難得一見的電商(究竟是什麼文法XD))。主要想藉由參加鐵人賽,半逼迫自己完成一個side project;其實一邊在做專案時,一邊也在想,有榮幸經歷AI的年代,也許很鉅細彌遺的教學不是最主要了,我們可能要更重視知道要做什麼,且將需求有條有理的整理出來,當然在剛轉工程師的時候單純google也有這種感覺,但不知道為什麼在現在體悟更深。沒原因的,忽然很想把這些感觸寫出來。接下來的自己繼續加油!
PS. 真的是滿想切腹的...Day15(昨天)文章明明都預寫完了,somehow就是沒發出去...所以鐵人賽就失敗了....不過我還是會照發T_T好煩喔