2024.02.14 TIL - 트러블슈팅(firebase collection()오류, authentication 로그인 로직

Innes·2024년 2월 14일
1

TIL(Today I Learned)

목록 보기
64/147
post-thumbnail

🏹 트러블슈팅

  1. firebase collection()오류
  • 에러 메시지 : FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

  • 원인 : 리액트에서 firestore의 정보 가져올때는 collection 부분 전체를 query로 감싸줘야함!

// ❌ 이전 코드
export const getUsersApi = async (email) => {
  try {
    const usersRef = (collection(db, 'users'), where('email', '==', email));
    const snapshot = await getDocs(usersRef);
    // ...생략
    
// ✅ 수정된 코드 (query로 감싸줌)
export const getUsersApi = async (email) => {
  try {
    const usersRef = query( 	// ⭐️ 기존의 (collection())을 query로 감싸주기
      collection(db, 'users'),
      where('email', '==', email)
    );
    const snapshot = await getDocs(usersRef);
    // ...생략
  • 참고사항 : firestore import 할 때 "...firebase/lite" 에서 lite 안 쓰면 에러 뜸

  1. 리덕스에서 가져온 값이 null로 뜰 때 확인해볼 것
  • 확인해볼 사항
    • 로그인한 이메일, 비밀번호가 firestore에 잘 저장되어있는지 확인해볼 것
    • 리덕스에서 return하는 값이 제대로 작성되어있는지 확인해볼 것
  • 해결된 코드는 아래 'authentication 로그인 로직' 에서 확인

내 경우에는 로그인한 이메일, 비밀번호가 authentication에는 가입되어있는데, firestore에는 저장되지 않은 값이어서 null로 뜨고있었다.
firestore에 저장된 이메일, 비밀번호로 넣어주니 제대로된 값을 가져올 수 있었다.


authentication 로그인 로직

// ✅ firestore에 있는 data 가져오는 api
export const getUsersApi = async (email) => {
  try {
    const usersRef = query(
      collection(db, 'users'),
      where('email', '==', email)
    );
    const snapshot = await getDocs(usersRef);

    const users = snapshot.docs.map((doc) => ({
      ...doc.data()
    }));
    console.log(snapshot, users);
    return users[0];
  } catch (error) {
    console.error('Error getting users data:', error);
    throw error;
  }
};

// ✅ 로그인 버튼 클릭시 dispatch로 정보 전달
const dispatch = useDispatch();
const users = useSelector((state) => state.user); // 리듀서에 넣은 state 불러오기

const onLoginConfirm = async () => {
    try {
      const userCredential = await 
      // authentication 회원가입
      signInWithEmailAndPassword(auth, email, pw);	
      
      const { accessToken, uid } = userCredential.user;
      
      // getUsersApi에 email 전달 후 실행
      // (firestore에서 image, nickname, email을 가져옴)
      const userInfo = await getUsersApi(email);
      console.log('userInfo:', userInfo);

      // authentication에서 가져온 값과 firestore에서 가져온 값을 dispatch로 보내줌
      dispatch(postUserData({ accessToken, userId: uid, email, ...userInfo }));

      // 리듀서 정상작동 확인
      console.log(users);	
      
      // authentication에 저장된 user 정보 확인
      console.log('user with login:', userCredential.user);
      
      alert('로그인 되었습니다.');
      setIsLoggedIn(true);
      setIsOpen(false);
    } catch (error) {
      const errorCode = error.code;
      const errorMessage = error.message;
      console.log('error with login:', errorCode, errorMessage);
    }
  };

// ✅ user reducer
const UPDATE_USER_DATA = 'user/UPDATE_USER_DATA';

export const updateUserData = (updateUser) => ({
  type: UPDATE_USER_DATA,
  updateUser
});

const initialState = {
  accessToken: null,
  email: null,
  userId: null,
  image: null,
  nickname: null
};

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case UPDATE_USER_DATA:
      return {
        ...state,
        ...action.updateUser
      };
    default:
      return state;
  }
};

export default userReducer;
profile
무서운 속도로 흡수하는 스폰지 개발자 🧽

0개의 댓글