[Expo]Firebase 연동 및 Google 로그인 구현 과정
Firebase를 활용한 프로젝트에서 인증 시스템을 구현하는 과정은 몇 가지 단계로 나눌 수 있습니다. 특히 에뮬레이터를 사용하여 개발 비용 없이 테스트 환경을 구축하는 것은 중요한 접근 방식입니다.
1. Firebase 초기화 설정
Firebase 서비스를 사용하기 위한 초기화 설정은 다음과 같이 구현했습니다
import {getApp, initializeApp} from '@react-native-firebase/app';
import { getAuth, connectAuthEmulator } from '@react-native-firebase/auth';
import { getFirestore, connectFirestoreEmulator } from '@react-native-firebase/firestore';
import { getStorage, connectStorageEmulator } from '@react-native-firebase/storage';
const app = getApp();
const auth = getAuth(app);
const firestore = getFirestore(app);
const storage = getStorage(app);
if (__DEV__) {
connectAuthEmulator(auth, 'http://localhost:9099');
connectFirestoreEmulator(firestore, 'localhost', 8080);
connectStorageEmulator(storage, 'localhost', 9199);
console.log('Firebase 에뮬레이터에 연결되었습니다.');
}
export { auth, firestore, storage };
이 코드는 Firebase의 주요 서비스(인증, Firestore, 스토리지)를 초기화하고, 개발 환경에서는 로컬 에뮬레이터에 연결하도록 구성됩니다. 에뮬레이터를 사용하면 실제 Firebase 비용 없이 개발 및 테스트가 가능합니다.
2. Google 로그인 구현
Google 로그인 기능은 @react-native-google-signin/google-signin 라이브러리를 활용하여 다음과 같이 구현했습니다
import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';
import { auth } from '../firebase/firebase';
import { GoogleAuthProvider } from '@react-native-firebase/auth';
// Google 로그인 초기화 (앱 시작 시 한 번만 호출)
export const configureGoogleSignIn = () => {
GoogleSignin.configure({
webClientId: "123935749466-0pos7sor5ufgmo0h9f9u32nl9mlk03ui.apps.googleusercontent.com", // 웹 클라이언트 ID
iosClientId: '123935749466-be4k50efmaeeme69q0o10tmpi5s1cs9l.apps.googleusercontent.com', // iOS 클라이언트 ID
offlineAccess: false, // 오프라인 액세스가 필요하지 않음
scopes: ['profile', 'email'] // 기본 스코프
});
};
// Google 로그인
export const signInWithGoogle = async () => {
try {
// Google Play 서비스 확인 (Android 전용)
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
// Google 로그인 수행
const userInfo = await GoogleSignin.signIn();
console.log('Google 로그인 성공:', userInfo);
// ID 토큰 확인
if (!userInfo.data?.idToken) {
throw new Error('Google에서 ID 토큰을 받지 못했습니다.');
}
// Firebase 인증에 사용할 Google 크레덴셜 생성
const googleCredential = GoogleAuthProvider.credential(userInfo.data.idToken);
// Firebase로 로그인
const userCredential = await auth.signInWithCredential(googleCredential);
console.log('Firebase 로그인 성공:', userCredential.user.uid);
return { user: userCredential.user, error: null };
} catch (error: any) {
console.error('Google 로그인 에러:', error);
// 에러 코드에 따른 처리
if (error.code) {
switch (error.code) {
case statusCodes.SIGN_IN_CANCELLED:
return { user: null, error: new Error('로그인이 취소되었습니다.') };
case statusCodes.IN_PROGRESS:
return { user: null, error: new Error('로그인이 이미 진행 중입니다.') };
case statusCodes.PLAY_SERVICES_NOT_AVAILABLE:
return { user: null, error: new Error('Google Play 서비스를 사용할 수 없습니다.') };
default:
return { user: null, error: new Error(`Google 로그인 오류: ${error.message}`) };
}
}
return { user: null, error };
}
};
이 코드는 Google 로그인 과정을 처리하며, 성공 시 Firebase 인증까지 완료합니다. 또한 다양한 오류 상황에 대한 처리도 포함되어 있습니다.
3. 테스트 계정 로그인 구현
개발 환경에서는 Google 로그인 대신 테스트 계정을 사용할 수 있도록 다음 기능을 구현했습니다
// 테스트 계정 로그인 (개발 환경용)
export const signInWithTestAccount = async () => {
try {
console.log("테스트 계정으로 로그인 시도...");
const testEmail = "test@example.com";
const testPassword = "password";
try {
// 기존 테스트 계정으로 로그인 시도
await auth.signInWithEmailAndPassword(testEmail, testPassword);
console.log("테스트 계정 로그인 성공");
return { user: auth.currentUser, error: null };
} catch (loginError) {
console.log("테스트 계정이 없어 새로 생성합니다", loginError);
// 계정이 없으면 새로 생성
const userCredential = await auth.createUserWithEmailAndPassword(
testEmail,
testPassword
);
console.log("테스트 계정 생성 및 로그인 성공");
return { user: userCredential.user, error: null };
}
} catch (error) {
console.error("테스트 로그인 에러:", error);
return {
user: null,
error: new Error("Firebase 에뮬레이터에 연결되어 있는지 확인하세요.")
};
}
};
이 기능은 Firebase 에뮬레이터에서 테스트 계정으로 로그인하거나, 계정이 없는 경우 새로 생성하는 로직을 포함합니다. 개발 과정에서 실제 Google 계정 없이도 인증 기능을 테스트할 수 있어 유용합니다.
4. 추가 인증 관련 기능
로그인 외에도 자동 로그인, 로그아웃, 상태 확인 등의 기능을 다음과 같이 구현했습니다
// 자동 로그인 시도 (이전 로그인 정보 사용)
export const signInSilently = async () => {
try {
// 이전에 로그인한 사용자가 있는지 확인
const isSignedIn = GoogleSignin.getCurrentUser();
if (!isSignedIn) {
return { user: null, error: null };
}
// 자동 로그인 시도
const userInfo = await GoogleSignin.signInSilently();
console.log('자동 로그인 성공:', userInfo);
// ID 토큰으로 Firebase 로그인
if (userInfo.data?.idToken) {
const googleCredential = GoogleAuthProvider.credential(userInfo.data.idToken);
const userCredential = await auth.signInWithCredential(googleCredential);
return { user: userCredential.user, error: null };
} else {
// ID 토큰이 없는 경우 Firebase 로그인 불가능
return { user: null, error: new Error('ID 토큰이 없습니다.') };
}
} catch (error: any) {
console.error('자동 로그인 에러:', error);
// 특정 에러 코드에 대한 처리
if (error.code === statusCodes.SIGN_IN_REQUIRED) {
// 사용자가 직접 로그인해야 함
return { user: null, error: null };
}
return { user: null, error };
}
};
// 로그아웃
export const signOut = async () => {
try {
// Google 로그인 로그아웃
await GoogleSignin.signOut();
// Firebase 로그아웃
await auth.signOut();
console.log('로그아웃 성공');
return { success: true, error: null };
} catch (error) {
console.error('로그아웃 에러:', error);
return { success: false, error };
}
};
// 현재 로그인 상태 확인
export const getCurrentUser = () => {
return auth.currentUser;
};
// 로그인 상태 변경 리스너
export const onAuthStateChanged = (callback: (user: any) => void) => {
return auth.onAuthStateChanged(callback);
};
// Google 연결 해제 (선택 사항)
export const revokeAccess = async () => {
try {
await GoogleSignin.revokeAccess();
await auth.signOut();
console.log('Google 연결 해제 및 로그아웃 성공');
return { success: true, error: null };
} catch (error) {
console.error('Google 연결 해제 에러:', error);
return { success: false, error };
}
};
이러한 기능들은 사용자 경험을 향상시키고, 다양한 인증 시나리오에 대응할 수 있게 해줍니다.
결론
Firebase 에뮬레이터와 Google 로그인 기능을 통합하여 비용 효율적이고 안정적인 인증 시스템을 구축할 수 있었습니다. 개발 환경에서는 테스트 계정을, 프로덕션 환경에서는 실제 Google 계정을 사용하는 유연한 접근 방식을 통해 개발 및 테스트 과정이 원활해졌습니다.
https://react-native-google-signin.github.io/docs/setting-up/expo
Expo setup | React Native Google Sign In
Prepare your Expo project
react-native-google-signin.github.io
https://react-native-google-signin.github.io/docs/original
Original Google sign in | React Native Google Sign In
To migrate to Universal sign in, follow this guide.
react-native-google-signin.github.io
https://rnfirebase.io/#prerequisites
React Native Firebase | React Native Firebase
Welcome to React Native Firebase! To get started, you must first setup a Firebase project and install the "app" module. React Native Firebase has begun to deprecate the namespaced API (i.e firebase-js-sdk < v9 chaining API). React Native Firebase will be m
rnfirebase.io