112. Handling the Response
npm create vue@latest
이 강의에서는 Firebase로부터 오는 응답을 처리하는 방법에 대해 설명합니다.
여기서는 createUserWithEmailAndPassword
함수를 사용하여 Firebase에 사용자 등록 요청을 보내고, 이 요청으로부터 오는 응답을 처리하는 과정을 다룹니다.
에러 처리
- Firebase로부터 오류 응답을 받을 수 있으므로, 이를 처리해야 합니다.
async/await
구문을 사용하고 있으므로,try/catch
블록을 사용하여 에러를 캐치합니다.catch
블록에는error
매개변수가 포함되어 있으며, 모든 오류는 코드와 메시지를 포함합니다.
하지만 구체적인 오류 내용 대신 일반적인 메시지를 사용자에게 표시하기로 합니다.
- Firebase로부터 오류 응답을 받을 수 있으므로, 이를 처리해야 합니다.
경고 메시지 업데이트
- 오류가 발생했을 때, 사용자에게 알리기 위해 경고 메시지를 업데이트합니다.
먼저information
속성을false
로 설정하여 폼을 다시 활성화시키고,alert
속성의 변형을 빨간색으로 설정합니다.
이는 일반적인 오류 메시지와 연관됩니다.
마지막으로, '예상치 못한 오류가 발생했습니다. 나중에 다시 시도해 주세요.'라는 메시지를 설정합니다.
- 오류가 발생했을 때, 사용자에게 알리기 위해 경고 메시지를 업데이트합니다.
변수 범위
userCredentials
변수가try/catch
블록 바깥에서 접근할 수 없으므로, 이 변수를 함수의 상단에서 정의하고 초기값을null
로 설정합니다.
사용자 등록 테스트
- 앱을 브라우저에서 열고 콘솔을 열어 오류없이 계정을 등록해보세요.
성공 메시지가 표시되며, 콘솔에서 사용자 자격 증명에 대한 정보를 볼 수 있습니다.
- 앱을 브라우저에서 열고 콘솔을 열어 오류없이 계정을 등록해보세요.
Firebase 콘솔 확인
- Firebase 콘솔로 이동하여 '인증' 페이지에서 사용자가 목록에 있는지 확인합니다.
새로고침하여 사용자가 리스트에 나타나는지 확인할 수 있습니다.
- Firebase 콘솔로 이동하여 '인증' 페이지에서 사용자가 목록에 있는지 확인합니다.
오류 테스트
- 같은 정보로 폼을 다시 제출하여 Firebase가 중복 이메일을 허용하지 않음을 확인합니다.
이 경우, 빨간색 경고 메시지가 표시됩니다.
- 같은 정보로 폼을 다시 제출하여 Firebase가 중복 이메일을 허용하지 않음을 확인합니다.
이 강의에서는 Firebase를 사용하여 사용자 등록 요청을 처리하고, 그 응답을 관리하는 방법을 설명하고 있습니다.
Firebase를 사용하면 백엔드 로직에 대해 걱정할 필요가 적어지며, 몇 번의 클릭으로 바로 사용할 수 있는 인증 시스템을 제공받을 수 있습니다.
Firebase는 요청을 보내고, 그들의 서버에서 정보를 검증한 후, 사용자의 자격 증명에 대한 응답을 제공합니다.
개발자는 Firebase가 제공하는 응답만을 처리하면 됩니다.
이러한 접근 방식은 백엔드로직을 간소화하고, 인증 시스템을 빠르게 구축할 수 있게 해줍니다.
src/components/RegisterForm.vue
<script setup lang="ts">
import { ref } from 'vue'
import { getAuth, createUserWithEmailAndPassword } from 'firebase/auth'
const schema = ref({
name: 'required|min:3|max:100|alpha_spaces',
email: 'required|min:3|max:100|email',
age: 'required|min_value:18|max_value:100',
password: 'required|min:9|max:100|excluded:password', // password 단어를 입력하면 유효성 검사를 통과할 수 없다.
confirm_password: 'passwords_mismatch:@password', // 비밀번호 입력할 때, 비밀번호 재확인차 입력하는 필드 // 위의 password 부분과 일치하는지 확인함
country: 'required|country_excluded:Antarctica',
tos: 'required'
})
const userData = ref({
country: 'USA'
})
const reg_in_submission = ref(false)
const reg_show_alert = ref(false)
const reg_alert_variant = ref('bg-blue-500')
const reg_alert_msg = ref('Please wait! Your acount is being created.')
const register = async (values: {
age: number
confirm_password: string
country: string
email: string
name: string
password: string
tos: number
}) => {
// VeeForm 안에 VeeField의 모든 유효성 검사를 통과해야지 values 값이 들어온다.
// ex.
// {
// age: 31
// confirm_password: "asdf"
// country: "Germany"
// email: "sdf@sdf.com"
// name: "sfdf"
// password: "asdf"
// tos: "1"
// }
reg_show_alert.value = true
reg_in_submission.value = true
reg_alert_variant.value = 'bg-blue-500'
reg_alert_msg.value = 'Please wait! Your account is being created.'
let userCred
try {
const auth = getAuth()
userCred = await createUserWithEmailAndPassword(auth, values.email, values.password)
} catch (error) {
reg_in_submission.value = false
reg_alert_variant.value = 'bg-red-500'
reg_alert_msg.value = 'An unexpected error occured. Please try again later.'
return
}
reg_alert_variant.value = 'bg-green-500'
reg_alert_msg.value = 'Success! Your account has been created.'
console.log(userCred)
}
</script>
<template>
<!-- Registration Form -->
<div
class="text-white text-center font-bold p-4 rounded mb-4"
v-if="reg_show_alert"
:class="reg_alert_variant"
>
{{ reg_alert_msg }}
</div>
<VeeForm :validation-schema="schema" @submit="register" :initial-values="userData">
<!-- Name -->
<div class="mb-3">
<label class="inline-block mb-2">Name</label>
<VeeField
type="text"
name="name"
class="block w-full py-1.5 px-3 text-gray-800 border border-gray-300 transition duration-500 focus:outline-none focus:border-black rounded"
placeholder="Enter Name"
/>
<ErrorMessage class="text-red-600" name="name" />
</div>
<!-- Email -->
<div class="mb-3">
<label class="inline-block mb-2">Email</label>
<VeeField
type="email"
name="email"
class="block w-full py-1.5 px-3 text-gray-800 border border-gray-300 transition duration-500 focus:outline-none focus:border-black rounded"
placeholder="Enter Email"
/>
<ErrorMessage class="text-red-600" name="email" />
</div>
<!-- Age -->
<div class="mb-3">
<label class="inline-block mb-2">Age</label>
<VeeField
type="number"
name="age"
class="block w-full py-1.5 px-3 text-gray-800 border border-gray-300 transition duration-500 focus:outline-none focus:border-black rounded"
/>
<ErrorMessage class="text-red-600" name="age" />
</div>
<!-- Password -->
<div class="mb-3">
<label class="inline-block mb-2">Password</label>
<VeeField name="password" :bails="false" #default="{ field, errors }">
<input
type="password"
class="block w-full py-1.5 px-3 text-gray-800 border border-gray-300 transition duration-500 focus:outline-none focus:border-black rounded"
placeholder="password"
v-bind="field"
/>
<div class="text-red-600" v-for="error in errors" :key="error">
{{ error }}
</div>
</VeeField>
</div>
<!-- Confirm Password -->
<div class="mb-3">
<label class="inline-block mb-2">Confirm Password</label>
<VeeField
type="password"
name="confirm_password"
class="block w-full py-1.5 px-3 text-gray-800 border border-gray-300 transition duration-500 focus:outline-none focus:border-black rounded"
placeholder="Confirm Password"
/>
<ErrorMessage class="text-red-600" name="confirm_password" />
</div>
<!-- Country -->
<div class="mb-3">
<label class="inline-block mb-2">Country</label>
<VeeField
as="select"
name="country"
class="block w-full py-1.5 px-3 text-gray-800 border border-gray-300 transition duration-500 focus:outline-none focus:border-black rounded"
>
<option value="USA">USA</option>
<option value="Mexico">Mexico</option>
<option value="Germany">Germany</option>
<option value="Antarctica">Antarctica</option>
</VeeField>
<ErrorMessage class="text-red-600" name="country" />
</div>
<!-- TOS -->
<div class="mb-3 pl-6">
<VeeField
type="checkbox"
name="tos"
value="1"
class="w-4 h-4 float-left -ml-6 mt-1 rounded"
/>
<label class="inline-block">Accept terms of service</label>
<ErrorMessage class="text-red-600 block" name="tos" />
</div>
<button
type="submit"
class="block w-full bg-purple-600 text-white py-1.5 px-3 rounded transition hover:bg-purple-700"
:disabled="reg_in_submission"
>
Submit
</button>
</VeeForm>
</template>
<style scoped></style>