사용자 계정 설정과 자동 로그인
Firebase Authentication을 통해 계정을 만들었으므로,
앱에서는 사용자의 계정 등록 정보 외에
사용자의 이름, 현재 상태, 사용자 소개 등의 추가적인 정보가 필요합니다.
계정 설정을 통해 이 추가정보를 사용자에게서 입력을 받아 Firestore에 저장합니다.
앱이 시작할 때 로그인 상태를 확인하여,
자동으로 로그인을 하고,
사용자의 계정 정보를 가져옵니다.
계정 설정
계정을 만들 때 이메일과 패스워드만으로 계정을 생성하였습니다.
계정 또한 Firebase Auth에 저장됩니다.
앱에서는 사용자의 계정 등록 정보 외에
사용자의 이름, 현재 상태, 사용자 소개 등의 추가적인 정보가 필요합니다.
앱에서는 이를 위하여 계정과는 별도의 계정 설정 정보를 Firestore의 profiles 컬렉션에 저장합니다.
계정 설정 정보는 계정 만들기를 성공하면
userId, 이메일 등은 계정 만들기를 통해 취득한 정보이므로 설정이 가능하고
이름, 상태, 소개 등은 사용자의 입력이 필요하므로 공란으로 저장을 하고
계정 설정 페이지로 이동합니다.
계정 설정 페이지에서 계정 설정 정보를 입력한 후 저장하기를 누르면 계정 설정 정보가 저장됩니다.
물론 계정 설정 정보는 언제든 수정이 가능합니다.
authStore
// 회원가입
const register = async (email, password) => {
try {
loading.value = true;
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
user.value = userCredential.user;
// 계정 만들기 후 Profile 저장
const profileData = {
userId: userCredential.user.uid,
email,
name: '',
status: '',
aboutMe: '',
createdAt: new Date(),
uids: [userCredential.user.uid],
};
await registerProfile(profileData);
router.push('/profile'); // 프로필 수정으로
} catch (error) {
alert('회원가입 실패: ' + error.message);
} finally {
loading.value = false;
}
};
// firestore에 계정 설정 저장
const registerProfile = async (profileData) => {
try {
await addDoc(collection(db, 'profiles'), profileData);
await fetchProfiles();
} catch (error) {
alert('Failed to register user: ' + error);
}
};
// 계정 설정 수정
const updateProfile = async (updatedProfile) => {
try {
loading.value = true;
const profileDocRef = doc(db, 'profiles', updatedProfile.id);
await updateDoc(profileDocRef, {
name: updatedProfile.name,
status: updatedProfile.status,
aboutMe: updatedProfile.aboutMe,
// 다른 필드도 필요에 따라 추가 가능
});
profile.value = { ...updatedProfile }; // 로컬 상태도 반영
loading.value = false;
alert('계정 정보를 수정했습니다.');
} catch (error) {
loading.value = false;
alert('계정 정보 수정 중 오류 발생: ' + error.message);
}
}
Profile.vue
<!-- src/views/Profile.vue -->
<template>
<v-container fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="10" md="6">
<v-card elevation="10" class="pa-4">
<v-card-title class="text-h6 font-weight-bold">계정 설정</v-card-title>
<v-card-text>
<v-form @submit.prevent="onUpdate" v-model="formValid" ref="formRef">
<v-text-field
v-model="auth.profile.name"
label="이름 또는 별명"
prepend-inner-icon="mdi-account"
required
/>
<v-text-field
v-model="auth.profile.status"
label="상태 메시지"
prepend-inner-icon="mdi-comment"
/>
<v-textarea
v-model="auth.profile.aboutMe"
label="자기소개"
auto-grow
prepend-inner-icon="mdi-information-outline"
/>
<v-text-field
v-model="auth.profile.email"
label="이메일"
prepend-inner-icon="mdi-email"
disabled
/>
<v-btn :loading="auth.loading" type="submit" color="primary" block class="mt-4">
저장하기
</v-btn>
</v-form>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useAuthStore } from '@/stores/authStore';
const auth = useAuthStore();
const formValid = ref(false);
const formRef = ref(null);
onMounted(() => {
if (!auth.profile) {
auth.fetchProfiles();
}
});
const onUpdate = () => {
if (formRef.value?.validate()) {
auth.updateProfile(auth.profile);
}
};
</script>
자동 로그인
Firebase Authentication으로 계정을 생성한 후에는,
사용자는 로그인을 한다는 것은 Firebase Authentication에 로그인했다는 것이고
이 정보는 Firebase가 자동으로 세션에 저장합니다.
onAuthStateChanged는 Firebase Authentication에서 제공하는 함수로,
사용자의 로그인 상태가 바뀔 때마다 자동으로 실행되는 리스너(listener) 입니다.
이를 통하여 사용자가 로그인 상태인지 여부를 알 수 있습니다.
auth store에 initializeAuth 함수는
onAuthStateChanged로 로그인 상태를 확인하여
전체 사용자의 계정을 가져오는 fetchProfiles()를 호출합니다.
authStore
// src/stores/authStore.js
// 로그인 상태 유지
const initializeAuth = () => {
onAuthStateChanged(auth, async (currentUser) => {
user.value = currentUser;
if (currentUser) await fetchProfiles();
});
};
// profile 정보 읽기
const fetchProfile = async (profileId) => {
try {
const profileRef = doc(db, 'profiles', profileId);
const profileSnap = await getDoc(profileRef);
if (profileSnap.exists()) {
profile.value = { id: profileId, ...profileSnap.data() };
} else {
console.log(`fetchProfile: ${profileId} 계정 설정 정보가 없습니다.`);
}
} catch (error) {
alert('Failed to fetch user: ' + error.message);
}
};
// 모든 사용자의 프로필 읽기
const fetchProfiles = async () => {
try {
profiles.length = 0;
const profileRef = collection(db, 'profiles');
const querySnapshot = await getDocs(profileRef);
querySnapshot.forEach(doc => profiles.push({ id: doc.id, ...doc.data() }));
if (user.value) {
const foundProfile = profiles.find(p => p.uids.includes(user.value.uid));
if (foundProfile) fetchProfile(foundProfile.id);
}
} catch (error) {
console.log('fetchProfiles: ' + error.message);
}
};
'Vue3, Firebase 프로젝트 - 채팅앱 VSignal' 카테고리의 다른 글
31. [따라하기] 비밀번호 재설정과 비밀번호 변경 (0) | 2025.05.05 |
---|---|
30. 비밀번호 변경과 비밀번호 리셋 (0) | 2025.05.04 |
28. 사용자 로그인 상태 감지하여 프로필 정보 가져오기 (1) | 2025.05.03 |
27. Vue 3 + Vuetify + Pinia + Firebase Firestore 기반의 계정 설정 (0) | 2025.05.03 |
26. [따라하기] Firebase Auth, Pinia Store 그리고 사용자 인증 (1) | 2025.05.02 |