깉이보면 좋은글
2023.09.06 - [JS/Next.js] - [Error] auth/invalid-api-key, Next.js 에서 환경변수
[Error] auth/invalid-api-key, Next.js 에서 환경변수
원인: Next.js Node환경 환경변수 발단 firebase를 이용해서 로그인 기능을 구현중 계속 `{code: "auth/invalid-api-key", message: "Your API key is invalid, please check you have copied it correctly."}` 에러메세지가 호출되었다
aliencoding.tistory.com
Firebase Authentication
파이어베이스로 사용자 로그인을 해보자!
SDK 설치 및 Firebase 초기화
파이어베이스 SDK를 설치해주자
npm install firebase
그런 다음 초기화
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
//...
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
Email과 비밀번호를 이용해서 로그인
firebase 예시
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
const auth = getAuth();
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ..
});
타입스크립트를 이용해 구현
export async function createUser(
email: string,
password: string,
userName: string
) {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
await updateProfile(user, { displayName: userName });
await setUserData(user);
return user; // 여기에서 user 객체를 반환합니다.
} catch (error) {
console.error("Error creating user:");
throw error;
}
}
try catch 문을 이용해 에러를 잡아내고 `createUserWithEmailAndPassword()` 함수에 참조값과 이메일과 비밀번호를 전달한 후에 생성된 유저정보를 받아와 `createUserWithEmailAndPassword()`로 생성된 유저정보에는 displayName값이 없기 때문에`updateProfile()`을 이용해 생성된 정보위에 displayName 값을 받아온 userName 값으로 변경해주고, 파이어베이스 파이어스토 유저 컬렉션에 해당 유저 정보를 전달하는 `setUserData(user)` 을 실행하고 user을 리턴하도록 하였다.
//SignupModal.tsx
"use client";
import { useState } from "react";
import { FirebaseError } from "firebase/app";
import { createUser } from "@/app/api/firebase";
import { User } from "firebase/auth";
type SignupModalProps = {
handleSignUpModalState: () => void;
handleSetUser: (user: User) => void;
};
export default function SignupModal({
handleSignUpModalState,
handleSetUser,
}: SignupModalProps) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [userName, setUserName] = useState(""); // 추가
const [errorMessages, setErrorMessages] = useState("");
const handleSignUp = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
await createUser(email, password, userName).then((user) => {
handleSignUpModalState();
handleSetUser(user);
});
} catch (error) {
if (error) {
const firebaseError = error as FirebaseError;
switch (firebaseError.code) {
case "auth/email-already-in-use":
setErrorMessages("이미 사용중인 이메일입니다.");
break;
case "auth/invalid-email":
setErrorMessages("유효하지 않은 이메일입니다.");
break;
case "auth/weak-password":
setErrorMessages("비밀번호는 6자리 이상이어야 합니다.");
break;
default:
setErrorMessages("회원가입에 실패했습니다.");
}
setTimeout(() => {
setErrorMessages("");
}, 3000);
}
console.log(error);
}
};
return (
<div className="flex flex-col items-center justify-center h-full gap-4">
<div className='w-full flex justify-center relative'>
<h1>Login</h1>
<button onClick={handleSignUpModalState} type="button" className='absolute right-0'>
X
</button>
</div>
<form onSubmit={handleSignUp}>
<div className="flex flex-col gap-4">
<input
type="email"
placeholder="email"
onChange={(e) => setEmail(e.target.value)}
required
className='border border-neutral-300 p-2 rounded-md'
/>
<input
type="password"
placeholder="password"
onChange={(e) => setPassword(e.target.value)}
required
className='border border-neutral-300 p-2 rounded-md'
/>
<input
type="text"
name="userName"
id="userName"
placeholder="userName"
onChange={(e) => setUserName(e.target.value)}
required
className='border border-neutral-300 p-2 rounded-md'
/>
<button
type="submit"
className={`btn_default ${
!email || !password || !userName ? "disabled" : ""
}`}
>
회원가입
</button>
{errorMessages && <span>{errorMessages}</span>}
</div>
</form>
</div>
);
}
form 문에서 e.preventDefault()을 실행시키기 위해서는 이벤트 타입으로 리액트에서 제공하는 `e: React.FormEvent` 를 사용해야 한다.
try catch문을 사용해 error를 핸들링 할때 swich 문을 이용해 에러코드에 해당하는 메세지를 유저에게 전달하고 `setTImeout()`을 이용해 일정시간뒤에 메세지가 사라지도록 하였다.
유저 생성시 데이터베이스에 유저정보 따로 저장하기
// firestore.ts
// db는 firebase.ts에서 가져옴
// export const db = getFirestore(app);
import { db } from "./firebase";
import axios from "axios";
// ...
export async function setUserData(user: User): Promise<void> {
await setDoc(doc(db, "account", user.uid), {
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
uid: user.uid,
});
}
firebase setDoc을 이용해 유저정보 저장을 따로 해주었다.
2023.08.25 - [JS/React] - "나의 일지"프로젝트(5)_handsontable, 파이어스토어 데이터 베이스
"나의 일지"프로젝트(5)_handsontable, 파이어스토어 데이터 베이스
이제 첫 리포트를 생성해보자~!! 작업일지 리포트는 테이블형태(엑셀)로 작성하고 엑셀과 csv 파일로 내보내고 불러오게 가능하도록 구상을 했다. 마침 테이블 형태 관련해서 좋은 글과 좋은 라
aliencoding.tistory.com
여기에서 파이어스토어를 다루는 법에 대해 적어두었다.