[Nuxt3] Firebase 데스크에서 실행합니까 서버에서 실행합니까
프론트 데스크에서부터 집행을 시작하다
왜냐하면db를 정의하기 전에 FirebaseApp 기반의 비동기 처리를 초기화하지 않았기 때문에db는undefined
<script setup lang="ts">
// これはうまくいく
const users = ref<User[]>([])
async getUsersTest(){
users.value = await useFirestore().getUsers()
}
// ページ読み込みの時にユーザー一覧を表示させようとして以下のように書くとエラーが出る
const users = await useFirestore().getUsers()
console.log(users)
</script>
<template>
<button @click="getUsersTest()">ユーザー取得</button>
</template>
expected first argument to collectin() to be a CollectionReference・・・
프런트에서 하는 방법.
클릭하여 보기
plugins/firebase.client.ts
import { defineNuxtPlugin, useState } from '#app'
import { FirebaseApp, initializeApp } from 'firebase/app'
import { Firestore, getFirestore } from 'firebase/firestore'
import { Auth, initializeAuth } from 'firebase/auth'
// Initialize Firebase
const firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
const firebaseApp:FirebaseApp = initializeApp(firebaseConfig)
export const db:Firestore = getFirestore(firebaseApp)
export const auth:Auth = initializeAuth(firebaseApp)
export default defineNuxtPlugin((nuxtApp) => {
useState('firebaseApp', () => firebaseApp)
useState('auth', () => auth)
useState('db', () => db)
})
composables
1. useFirestore.ts
compoosable의 함수는 모두Promise를 되돌려줍니다. 예를 들어 쓰기에 성공한 경우'success'의res를 되돌려주고 실패한 경우'failure'의res를 되돌려줍니다.
import {
Firestore,
collection,
query,
where,
getDocs,
doc,
getDoc
} from 'firebase/firestore';
type User = {
id:String,
name:String
}
type Users = Array<User>
export const useFirestore = () => {
const db:Firestore = useState('db').value;
// 全ユーザーを取得
async function getUsers(){
return new Promise(async(resolve, reject)=>{
const q = query(
collection(db, 'users'),
);
const querySnapshot = await getDocs(q);
const users:Users = querySnapshot.docs.map((doc) => {
const data = doc.data()
const user:User = {
id:doc.id,
name:data.name
}
return user
});
resolve(users)
})
};
async function getUserById(id:string){
return new Promise(async(resolve, reject)=>{
const docRef = doc(db, 'users', id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
const data = docSnap.data()
const user:User={
id:docSnap.id,
name:data.name
}
resolve(user)
} else {
reject(null)
}
})
}
async function getHashiraUsers(){
return new Promise(async(resolve, reject)=>{
const q = query(
collection(db, 'users'),
where('hashira','==',true)
);
const querySnapshot = await getDocs(q);
const users:Users = querySnapshot.docs.map((doc) => {
const data = doc.data()
const user:User = {
id:doc.id,
name:data.name
}
return user
});
resolve(users)
})
}
return {
getUsers,getUserById,getHashiraUsers
};
};
2. useAuth.ts
import {
Auth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
onAuthStateChanged,
signOut
} from 'firebase/auth'
export const useAuth = () => {
const currentUser = ref<T>(null)
const auth:Auth = useState('auth').value
async function signUp(email:string, password:string){
return new Promise((resolve)=>{
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// サインアップできたらログインする
const currentUser = userCredential.user;
resolve("success")
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
resolve(errorCode)
});
})
}
async function passwordSignIn(email:string,password:string){
return new Promise((resolve)=>{
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// ログインできた時
currentUser.value = userCredential.user
resolve('success')
})
.catch((error) => {
// ログインできていない時
resolve(error)
})
})
};
function getUserData(){
console.log(`getUserDataが呼び出された`)
onMounted(() => {
onAuthStateChanged(auth, (currentUser) => {
if (currentUser) {
console.log(`currentUserあり`)
currentUser.value = currentUser
}else{
console.log(`currentUserなし`)
user.value = null
}
})
})
}
async function signout() {
return new Promise((resolve)=>{
signOut(auth)
.then(()=>{
currentUser.value = null
resolve("success")
})
.catch((error)=>{
resolve(error)
})
})
}
return {
signUp, passwordSignIn, signout, currentUser, getUserData
};
};
app
app.vue
<script setup lang="ts">
const {signUp, passwordSignIn, signout, currentUser, getUserData} = useAuth();
const router = useRouter()
const email = ref<String>('[email protected]')
const password = ref<String>('password')
const message = ref<String>('ログインしていません')
const items = [
{
title:'ダッシュボード',
to:'/',
icon:''
},{
title:'authのテスト',
to:'/authtest',
icon:''
},{
title:'storeのテスト',
to:'/dbtest',
icon:''
}
]
async function createAccount(){
const res:String = await signUp(email.value,password.value)
if(res=="success"){
// ダッシュボードに遷移するなど
}else if(res=="email-already-in-use"){
message.value = '既にアカウントを作成されているメールアドレスです'
}
}
async function login(){
const res:string = await passwordSignIn(email.value,password.value)
console.log(`ログイン結果, ${res}`)
if(res==="success"){
// ダッシュボードに遷移するなど
console.log(`ログインしました`)
}else if(/^.+wrong-password.+$/.test(res)){
message.value = `パスワードが間違っています`
}else if(/^.+user-not-found.+$/.test(res)){
message.value = `メールアドレスが間違っています`
}else{
message.value = `エラーが発生しました`
}
}
async function logout(){
const res:string = await signout()
console.log(`ログアウト結果, ${res}`)
if(res=="success"){
router.push('/')
message.value = 'ログアウトしました'
}else{
message.value = 'ログアウトに失敗しました。もう一度やり直してください'
}
}
</script>
<template>
<div style="outline:1px solid;height:50px;display:flex;justify-content: space-between;">
<h1 style="margin:0 10px;">Nuxt3</h1>
<div v-if="currentUser">{{currentUser.uid}}</div>
<button v-if="currentUser" @click="logout">ログアウト</button>
</div>
<div v-if="currentUser" style="display:flex">
<div style="outline:1px solid;width:150px;height:90vh">
<ul style="list-style-type: none;padding:10px">
<li v-for="item of items" :key="item.title">
<NuxtLink :to="item.to">{{item.title}}</NuxtLink>
</li>
</ul>
</div>
<div style="padding:10px">
<NuxtPage/>
</div>
</div>
<div v-else style="margin:0 auto;width:30vw">
{{message}}
<div>
<input type="text" id="email" v-model="email" placeholder="メールアドレス">
</div>
<div>
<input type="text" id="password" v-model="password" placeholder="パスワード">
</div>
<button @click="createAccount">サインアップ</button>
<button @click="login">ログイン</button>
</div>
</template>
pages
authtest.vue
<script setup lang="ts">
const {signUp, passwordSignIn, signout, user} = useAuth();
const email = ref<String>('[email protected]')
const password = ref<String>('password')
const message = ref<String>('')
async function createAccount(){
const res:String = await signUp(email.value,password.value)
if(res=="success"){
// ダッシュボードに遷移するなど
}else if(res=="email-already-in-use"){
message.value = '既にアカウントを作成されているメールアドレスです'
}
}
async function login(){
const res:string = await passwordSignIn(email.value,password.value)
console.log(`ログイン結果, ${res}`)
if(res==="success"){
// ダッシュボードに遷移するなど
console.log(`ログインしました`)
}else if(/^.+wrong-password.+$/.test(res)){
message.value = `パスワードが間違っています`
}else if(/^.+user-not-found.+$/.test(res)){
message.value = `メールアドレスが間違っています`
}else{
message.value = `エラーが発生しました`
}
}
async function logout(){
const res:string = await signout()
console.log(`ログアウト結果, `)
if(res=="success"){
// ログインページに遷移するなど
}else{
message.value = 'ログアウトに失敗しました。もう一度やり直してください'
}
}
</script>
<template>
<input
type="text"
id="email"
v-model="email"
placeholder="メールアドレス"
>
<input
type="text"
id="password"
v-model="password"
placeholder="パスワード"
>
<button @click="createAccount">サインアップ</button>
<button @click="login">ログイン</button>
<button @click="logout">ログアウト</button>
<div>メッセージ</div>
<div>{{message}}</div>
<div>ログインユーザー情報</div>
<div>{{user}}</div>
</template>
dbtest.vue
<script setup lang="ts">
type User = {
id:String,
name:String
}
type Users = Array<User>
const users = ref<Users>()
const user = ref<User>()
const { getUsers, getUserById, getHashiraUsers } = useFirestore();
async function test1(){
users.value = await getUsers()
}
async function test2() {
user.value = await getUserById('tanjiro')
}
async function test3(){
users.value = await getHashiraUsers()
}
async function test4(){
users.value = []
user.value=null
}
</script>
<template>
<div>
<button @click="test1">全ユーザーを取得</button>
<button @click="test2">炭治郎を取得</button>
<button @click="test3">柱を取得</button>
<button @click="test4">クリア</button>
<div style="height:200px;outline:solid 1px">
ここにusersを表示
<ul>
<li v-for="user of users" :key="user.id">{{user.name}}</li>
</ul>
</div>
<div style="height:300px;outline:solid 1px">
ここにuserを表示
<div>{{user}}</div>
</div>
</div>
</template>
참고 자료
nuxt3+firebasev9를 시도해 보세요.
How to integrate Firebase v9 with Nuxt3? · Discussion #2404 · nuxt/framework
서버에서 실행
Reference
이 문제에 관하여([Nuxt3] Firebase 데스크에서 실행합니까 서버에서 실행합니까), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/yuta_enginner/articles/f2eb0d4f36dfc7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)