0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Expo SDK 53 × Firebase Auth の永続化ができない理由と、2025年時点での対策

Last updated at Posted at 2025-05-26

久しぶりの備忘録 かつ、疲労困憊の脳味噌でChatGPTに書かせています。
ハルシネーション検証・EAS build版での実行結果を踏まえた加筆修正はまた後日。

はじめに

Expo+Firebaseでの認証実装時の、永続化(persistence)の設定にハマったので備忘録に残します。
「getReactNativePersistence」が動かず、警告が消せない状況に悩まされました。
2025年5月時点での最新状況と、「今できる最適な対応」 を整理しておきます。

前提環境

  • Expo SDK 53
  • Firebase JS SDK 11.8.1
  • TypeScript(Hermes有効)
  • @react-native-async-storage/async-storage導入済

1. 「getReactNativePersistence」が使えない理由

Expo SDK 50以降、Firebase v10以降では、

  • firebase/auth/react-native は廃止
  • firebase/auth からも getReactNativePersistence のエクスポートがなくなった

このため、以前までのサンプルコードがそのままでは動きません。

2. 警告が出る現象と、Expo Goの制約

開発中、getAuth(app) だけで認証を使うと下記の警告が出ます。

@firebase/auth: Auth: You are initializing Firebase Auth for React Native without providing AsyncStorage. Auth state will default to memory persistence...

つまり「永続化(アプリ再起動後もログイン状態を保持)」が無効になり、毎回サインインが必要になります。

Expo Goでは、getReactNativePersistenceがランタイムで利用できません(Hermes/Metroの制約)。
そのため、開発中はこの警告を回避できず、永続化も効きません。

3. 本番環境での正しい対応(EAS Build・bare)

永続化を有効にするには、EAS Buildやbareワークフローでアプリをビルドし、
その環境で getReactNativePersistence を利用する必要があります。
Expo Goでは無理ですが、EAS Build後はPersistenceが機能します。

4. 実行環境ごとの分岐方法(2025年最新)

Expo SDK 50以降は
Constants.executionEnvironment
で、「Expo Go」「EAS Build(bare)」などの実行環境を判別できます。

import Constants from "expo-constants";

if (Constants.executionEnvironment === "bare") {
  // 本番/EAS Build(永続化できる環境)
} else {
  // Expo GoやWeb(永続化は諦める)
}

5. 実際のコード例

import { initializeApp } from "firebase/app";
import { getAuth, initializeAuth, Auth } from "firebase/auth";
import AsyncStorage from "@react-native-async-storage/async-storage";
import Constants from "expo-constants";

const firebaseConfig = {
  // ...Firebaseの設定...
};

const app = initializeApp(firebaseConfig);

let auth: Auth;

if (Constants.executionEnvironment === "bare") {
  // Expo GoやWebはgetAuthのみで利用(永続化は効かない)
  auth = getAuth(app);
} else {
  // EAS Buildやbareのときだけ永続化を明示的に設定
  const { getReactNativePersistence } = require('firebase/auth');
  auth = initializeAuth(app, {
    persistence: getReactNativePersistence(AsyncStorage),
  });
}

export { auth };

※ require をif文の中に書くことで、Expo Goでもクラッシュしません。

6. まとめ

  • Expo GoではFirebase Authの永続化(persistence)はできない
  • EAS Buildやbareアプリでのみ有効
  • 実行環境の分岐には Constants.executionEnvironment を使うと安全
  • 警告が消えないのは仕様と割り切るのが現状の正解

おわりに

Firebase Authの永続化は、Expo Go開発時には割り切るしかありません。
本番環境でだけPersistenceが効くよう、分岐を入れて管理するのが無難です。

同じように詰まった方の参考になれば幸いです。
他にも気づいた点や新情報があれば、ぜひコメントで教えてください。

蛇足

Firestoreルールでauth使いたい&自動サインインにしたいときに使える 匿名認証 というものを今回初めて知りました。ExpoもReactNativeも、しばらく見ない間にいろいろ変わったなぁ…

  useEffect(() => {
    // アプリ起動時に現在の認証状態を確認
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (!user) {
        // ユーザーが未ログインなら匿名ログインを実行
        signInAnonymously(auth)
          .then(() => console.log('匿名ユーザーでサインインしました'))
          .catch((error) => console.error('匿名ログインに失敗:', error));
      }
      // ログイン済み (user が存在) の場合は何もしない(既存ユーザーを維持)
    });
    return unsubscribe; // コンポーネントアンマウント時にリスナー解除
  }, []);
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?