Open5

ReactNativeでTabとFirebase Authを両立させる

kabewallkabewall

現状

基本的にはexpo router のTab

やりたいこと

  • ReactNativeでFirebase Authを有効にする。
  • ログイン前と後で、routeを振り分ける
    • ログインしてない時は初期画面A、ログインしている時は初期画面Bのようにしたい
kabewallkabewall

https://rnfirebase.io/auth/usage#listening-to-authentication-state

これを元に、firebaseAuth.tsを実装。ログイン自体は成功

src/libs/firebase/firebaseAuth.ts
import { getApp } from "@react-native-firebase/app"
import auth, { FirebaseAuthTypes } from "@react-native-firebase/auth"
import { useEffect, useState } from "react"

export const useFirebaseAuth = () => {
  const [isInitialized, setIsInitialized] = useState<boolean>(true)
  const [user, setUser] = useState<FirebaseAuthTypes.User | null>(null)

  function onAuthStateChanged(user: FirebaseAuthTypes.User | null) {
    setUser(user)
    if (isInitialized) {
      setIsInitialized(false)
    }
    console.log(`user email = ${user?.email}`)
  }

  function loginWithEmailAndPassword(email: string, password: string) {
    auth(getApp())
      .signInWithEmailAndPassword(email, password)
      .then(() => {
        console.log("login")
      })
      .catch((error) => {
        console.log(error)
      })
  }

  function logout() {
    auth(getApp()).signOut()
  }

  useEffect(() => {
    const subscriber = auth(getApp()).onAuthStateChanged(onAuthStateChanged)
    return subscriber
  }, [])

  return { isInitialized, user, loginWithEmailAndPassword, logout }
}

kabewallkabewall

rootの_layout.tsxにリダイレクトを導入したら、いけた

src/app/_layout.tsx
import { Stack, useRouter } from "expo-router"
import "../../global.css"
import { SafeAreaView } from "react-native-safe-area-context"
import { useEffect } from "react"
import { useFirebaseAuth } from "@/libs/firebase/firebaseAuth"

export default function RootLayout() {
  const { user, isInitialized } = useFirebaseAuth()
  const router = useRouter()

  useEffect(() => {
    if (!isInitialized) return
    if (user) {
      router.replace("/")
    } else {
      router.replace("/(beforeAuth)/SignInView")
    }
  }, [user, isInitialized])

  return (
    <SafeAreaView style={{ flex: 1 }} className="font-loveat-font">
      <Stack>
        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
        <Stack.Screen
          name="StoreDetailView/[placeId]"
          options={{ presentation: "modal", headerShown: false }}
        />
      </Stack>
    </SafeAreaView>
  )
}

kabewallkabewall

一瞬、ログイン後の画面見えて、ログイン画面に戻るアニメーションつくの、気に食わない