🔥

React NativeでGoogleログインとFirebase認証を連携する方法

に公開

React Nativeでアプリを作っていて「Googleアカウントでログインさせたい」「ログイン状態を保持して次の画面に進ませたい」と思ったのに、意外と詰まってしまいました。この記事では、GoogleログインとFirebaseの認証を連携し、ログイン後に自動で別画面に遷移させる方法を、エラーの対処方法も含めて解説します。

🎯 ゴール

  • React Native アプリで Google ログインできる
  • Firebase のユーザー認証に連携できる
  • ログイン成功後に自動でメイン画面に遷移できる

🔧 1. Firebaseでの設定手順

✅ Firebase プロジェクトの作成

Firebase Console(https://console.firebase.google.com/)で新しいプロジェクトを作成しましょう。

✅ Androidアプリを登録

  1. Firebaseのプロジェクト設定から "Androidアプリ追加"
  2. パッケージ名(例:com.tamago.recipeai)を入力
  3. google-services.json をダウンロードして android/app/ に配置

この android/app/ フォルダは、npx create-expo-app などでプロジェクト作成後、npx expo prebuild や npx expo run:android などのネイティブコード生成系コマンドを実行したときに生成されます。

✅ SHA-1フィンガープリントの登録

SHA-1が登録されていないと、Googleログインで idToken が取得できず、エラーになります。

keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore

このSHA-1を Firebase の Android 設定に追加します。

✅ Google認証を有効にする

Firebase Console > Authentication > Sign-in method > Google を有効にします

⚙️ 2. AndroidアプリのGradle設定

android/build.gradle

dependencies {
        classpath('com.google.gms:google-services:4.4.2')
}

android/app/build.gradle

apply plugin: 'com.google.gms.google-services'

📦 3. Google Sign-In ライブラリの設定

npx expo install @react-native-google-signin/google-signin
npx expo install @react-native-async-storage/async-storage

🔥 4. Firebaseの初期化設定(firebaseConfig.js)

React Native環境でFirebaseを初期化し、認証情報(ログイン状態など)を永続化するための設定を行います。

import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import {
  initializeAuth,
  getReactNativePersistence,
} from 'firebase/auth';
import AsyncStorage from '@react-native-async-storage/async-storage';

const firebaseConfig = {
  apiKey: Constants.expoConfig.extra.EXPO_PUBLIC_FIREBASE_API_KEY,
  // 他の設定も同様に記載
};

const app = initializeApp(firebaseConfig);
const auth = initializeAuth(app, {
  persistence: getReactNativePersistence(AsyncStorage),
});

export { auth, app };
  • initializeApp: Firebaseアプリを初期化する関数。この1行で、Firebaseの機能(認証・DBなど)をアプリ内で使えるようになります。
  • getFirestore: Firestore(NoSQLデータベース)を使いたい場合に必要。
  • initializeAuth: 認証機能(ログイン/ログアウトなど)を使うための初期化関数。通常の getAuth(app) ではWeb向けの初期化になります。
  • getReactNativePersistence: React Native特有の「永続化機能」を使うための関数。
  • AsyncStorage: ログイン状態などをアプリに保存しておくための仕組み(スマホのローカルストレージのようなもの)。
  • firebaseConfig: Firebase プロジェクトごとの設定情報(APIキーなど)。通常 .env や app.config.js に隠しておき、expo-constants などを通して読み込む。

🔐 5. Googleログイン処理(auth.js)

ユーザーが「Googleでログイン」ボタンを押したときに実行される非同期関数の実装です。

import { GoogleSignin } from '@react-native-google-signin/google-signin';
import { GoogleAuthProvider, signInWithCredential } from 'firebase/auth';
import { auth } from '../../firebaseConfig';

const googleSignIn = async () => {
  try {
    await GoogleSignin.hasPlayServices();
    const userInfo = await GoogleSignin.signIn();

    const idToken = userInfo?.idToken || userInfo?.data?.idToken;
    const credential = GoogleAuthProvider.credential(idToken);
    await signInWithCredential(auth, credential);
    router.replace('特定の画面パス');
  } catch (error) {
    console.error("Google Sign-In Error", error);
  }
};
  • hasPlayServices:Androidで Google Play Services が有効か確認。
  • signIn:Googleアカウント選択画面が表示され、ユーザー情報を取得します。
  • credential:Firebaseに渡すための「Googleのログイン情報(credential)」を作成。
  • signInWithCredential:Firebaseに対してこの credential を使ってログイン。この時点でFirebaseのログイン状態が更新され、onAuthStateChanged が発火します。

🧩 トラブルシューティングまとめ

症状 原因 対処法
google-services.json が効かない build.gradle 設定不足 apply plugin や classpath を見直す
FirebaseError: Firebase: Error (auth/argument-error). idTokenの指定誤り、or Firebase に SHA-1 を登録していない SHA-1を登録し、userInfo.data.idToken を使う
onAuthStateChanged is not a function auth の初期化方法が不正 initializeAuth を使用し AsyncStorage をセットする
No matching client found for package name 'com.tamago.recipeai' google-services.json に登録されたパッケージ名と実際のアプリのパッケージ名が一致していない Firebase に正しいパッケージ名でアプリを登録し直す
adb: failed to install ... INSTALL_FAILED_UPDATE_INCOMPATIBLE 署名が異なるアプリをインストールしようとした エミュレーターから既存アプリを削除してから再インストール

✅ 結果:React NativeやFirebaseを利用したログイン実装

これで、以下が実現できました:

  • Googleログインできる
  • Firebase Authと連携

SHA-1やパッケージ名など設定を一致させる必要がある箇所が多く、意外と手こずりましたが、1つ1つ丁寧に確認していくと、誤りの箇所を特定できました。

Discussion