Skip to content

auth().onAuthStateChanged does not always trigger after sign-in on Android in React Native 0.77 #8374

@KAMRONBEK

Description

@KAMRONBEK

Hi Everybody, Any help would be greatly appreciated! auth().onAuthStateChanged is not working properly. On Android, after signing in, sometimes auth().onAuthStateChanged does not trigger. For example, after building the APK, signing in doesn't work at all. However, everything works fine on iOS.
Additionally, after uninstalling and rebuilding the app, this issue sometimes occurs. But when I completely close the app and reopen it, I find that the user is already signed in.
Thank you in advance for any assistance!

Expected Behavior:
auth().onAuthStateChanged should always trigger when a user signs in.

Current Behavior:
Sometimes, auth().onAuthStateChanged does not execute on Android, and the authenticated user state is not detected.

import React, { useContext, useEffect, useRef, useState } from 'react'
import analytics from '@react-native-firebase/analytics'
import Toast from 'react-native-toast-message'
import { OverflowMenuProvider } from 'react-navigation-header-buttons'
import RNBootSplash from 'react-native-bootsplash'
import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth'
import { NavigationContainer } from '@react-navigation/native'
import { AuthContext, UserFoundStates } from '../config/auth_context'
import { getUsersCountById } from '../api/firestore/get-users-by-id'
import PortalHost from '../components/portal/portal-host'
import AuthNavigator from './auth_navigator'
import RootNavigator from './root'
import { navRef } from './root_navigation_ref'
import { handleAppUpdates } from '../utils/app-update-handler'
import { UserContextProvider } from '../config/user_context'

const Navigator = () => {
const [initializing, setInitializing] = useState(true)
const { authUser, setAuthUser, userFound, setUserFound } =
useContext(AuthContext)
const routeNameRef = useRef()

console.log('auth.currentUser', auth().currentUser)

useEffect(() => {
handleAppUpdates()
}, [])

useEffect(() => {
const handleAuthChange = (user: FirebaseAuthTypes.User | null) => {
setUserFound(UserFoundStates.InProgress)
setAuthUser(user ?? undefined)
}

const subscription = auth().onAuthStateChanged(handleAuthChange)
return () => subscription()
// eslint-disable-next-line react-hooks/exhaustive-deps

}, [])

useEffect(() => {
if (authUser) {
getUsersCountById(authUser.uid).then((count) => {
if (initializing) setInitializing(false)
if (count !== 0) {
setUserFound(UserFoundStates.Found)
} else {
setUserFound(UserFoundStates.NotFound)
}
})
} else {
setUserFound(UserFoundStates.NotFound)
if (initializing) setInitializing(false)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [authUser])

if (initializing) {
return null
}

return (

<NavigationContainer
ref={navRef}
onReady={() => {
routeNameRef.current = navRef.current?.getCurrentRoute().name
RNBootSplash.hide({ fade: true })
}}
onStateChange={async () => {
const previousRouteName = routeNameRef.current
const currentRouteName = navRef.current.getCurrentRoute().name

      if (previousRouteName !== currentRouteName) {
        await analytics().logScreenView({
          screen_name: currentRouteName,
          screen_class: currentRouteName,
        })
      }

      // Save the current route name for later comparison
      routeNameRef.current = currentRouteName
    }}>
    <OverflowMenuProvider>
      {userFound === UserFoundStates.Found ? (
        <UserContextProvider userId={authUser?.uid}>
          <RootNavigator />
        </UserContextProvider>
      ) : (
        <AuthNavigator />
      )}
    </OverflowMenuProvider>
    <Toast ref={(ref) => Toast.setRef(ref)} />
  </NavigationContainer>
</PortalHost>

)
}

export default Navigator

package.json:
"scripts": {
"android": "react-native run-android --mode=prodDebug",
"android:staging": "react-native run-android --mode=stagingDebug --appIdSuffix=staging",
"ios": "react-native run-ios",
"ios:staging": "react-native run-ios --scheme SwishStaging Debug",
"start": "react-native start",
"test": "jest",
"pods": "cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install",
"lint": "eslint . --ext .ts,.tsx,.js,.jsx",
"lint:fix": "eslint . --ext .ts,.tsx,.js,.jsx --fix --quiet",
"format": "prettier --check .",
"format:fix": "prettier --write ."
},
"dependencies": {
"@expo/react-native-action-sheet": "^3.9.0",
"@invertase/react-native-apple-authentication": "^2.3.0",
"@react-native-async-storage/async-storage": "^1.18.2",
"@react-native-camera-roll/camera-roll": "^7.9.0",
"@react-native-clipboard/clipboard": "^1.14.1",
"@react-native-community/datetimepicker": "^8.2.0",
"@react-native-community/push-notification-ios": "^1.10.1",
"@react-native-community/slider": "^4.3.1",
"@react-native-firebase/analytics": "^21.7.1",
"@react-native-firebase/app": "^21.7.1",
"@react-native-firebase/auth": "^21.7.1",
"@react-native-firebase/crashlytics": "^21.7.1",
"@react-native-firebase/dynamic-links": "^21.7.1",
"@react-native-firebase/firestore": "^21.7.1",
"@react-native-firebase/functions": "^21.7.1",
"@react-native-firebase/messaging": "^21.7.1",
"@react-native-firebase/storage": "^21.7.1",
"@react-native-google-signin/google-signin": "^13.1.0",
"@react-native-picker/picker": "^2.9.0",
"@react-navigation/bottom-tabs": "~6.6.1",
"@react-navigation/core": "~6.4.17",
"@react-navigation/native": "~6.1.18",
"@react-navigation/native-stack": "~6.10.1",
"@react-navigation/stack": "~6.4.1",
"country-state-city": "^3.2.1",
"fbjs": "^3.0.5",
"geofirestore": "5.2.0",
"geokit": "1.1.0",
"lodash": "4.17.20",
"moment": "2.29.1",
"promise.allsettled": "^1.0.4",
"react": "18.3.1",
"react-native": "0.77.0",
"react-native-bootsplash": "~6.3.2",
"react-native-calendar-events": "^2.2.0",
"react-native-config": "^1.5.0",
"react-native-device-info": "^8.7.1",
"react-native-draggable-flatlist": "^4.0.1",
"react-native-geocoding": "^0.5.0",
"react-native-geolocation-service": "^5.3.1",
"react-native-gesture-handler": "~2.22.0",
"react-native-get-random-values": "^1.11.0",
"react-native-global-props": "^1.1.5",
"react-native-google-places-autocomplete": "^2.5.7",
"react-native-image-crop-picker": "^0.41.2",
"react-native-international-phone-number": "^0.7.6",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-lightbox-v2": "^0.9.0",
"react-native-linear-gradient": "^2.5.6",
"react-native-localize": "^2.0.3",
"react-native-maps": "^1.20.1",
"react-native-permissions": "^4.1.5",
"react-native-picker-select": "^9.3.1",
"react-native-push-notification": "^8.1.1",
"react-native-qrcode-svg": "^6.1.2",
"react-native-reanimated": "^3.16.7",
"react-native-safe-area-context": "^5.2.0",
"react-native-screens": "^4.6.0",
"react-native-svg": "^15.8.0",
"react-native-toast-message": "^1.6.0",
"react-native-url-polyfill": "^1.3.0",
"react-native-webview": "^13.13.2",
"react-navigation-header-buttons": "^10.0.0",
"rn-fetch-blob": "^0.12.0",
"use-memo-one": "^1.1.1",
"uuid": "^11.0.4"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@faker-js/faker": "8.3.1",
"@react-native-community/cli": "15.0.1",
"@react-native-community/cli-platform-android": "15.0.1",
"@react-native-community/cli-platform-ios": "15.0.1",
"@react-native/babel-preset": "0.77.0",
"@react-native/eslint-config": "0.77.0",
"@react-native/metro-config": "0.77.0",
"@react-native/typescript-config": "0.77.0",
"@testing-library/react-native": "^13.0.1",
"@types/jest": "^29.5.13",
"@types/lodash": "4.14.167",
"@types/promise.allsettled": "^1.0.3",
"@types/react": "^18.2.6",
"@types/react-native-global-props": "^1.1.1",
"@types/react-native-push-notification": "^7.3.3",
"@types/react-test-renderer": "^18.0.0",
"@types/uuid": "^10.0.0",
"babel-plugin-module-resolver": "^5.0.2",
"deprecated-react-native-prop-types": "^4.2.1",
"detox": "^20.20.3",
"eslint": "^8.49.0",
"eslint-config-airbnb-typescript": "12.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-detox": "^1.0.0",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jsx-a11y": "6.3.1",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-unused-imports": "^4.1.4",
"husky": "^9.1.7",
"jest": "^29.6.3",
"lint-staged": "^15.2.10",
"prettier": "3.3.3",
"react-test-renderer": "18.3.1",
"ts-jest": "^28.0.4",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}

firebase.json:
{
"react-native": {
"crashlytics_debug_enabled": false,
"crashlytics_disable_auto_disabler": true,
"crashlytics_auto_collection_enabled": true,
"crashlytics_is_error_generation_on_js_crash_enabled": true,
"crashlytics_javascript_exception_handler_chaining_enabled": false
}
}

android/build.gradle:
buildscript {
ext {
buildToolsVersion = "35.0.0"
minSdkVersion = 24
compileSdkVersion = 35
targetSdkVersion = 34
ndkVersion = "27.1.12297006"
kotlinVersion = "2.0.21"

    // https://stackoverflow.com/questions/74085319/class-was-expected-declaration-of-com-google-android-gms-location-fusedlocatio
    googlePlayServicesVersion = "21.0.1"
    googlePlayServicesAuthVersion = "20.7.0"

    // https://github.com/react-native-device-info/react-native-device-info/issues/1640#issuecomment-2243533852
    googlePlayServicesIidVersion = "17.0.0"
}
repositories {
    google()
    mavenCentral()
}
dependencies {
    classpath("com.android.tools.build:gradle")
    classpath("com.facebook.react:react-native-gradle-plugin")
    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
    classpath 'com.google.gms:google-services:4.4.2'
    classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
}

}

apply plugin: "com.facebook.react.rootproject"

android/app/build.gradle:

Activity

changed the title [-]auth().onAuthStateChanged does not always trigger after sign-in on Android[/-] [+]auth().onAuthStateChanged does not always trigger after sign-in on Android in React Native 0.77[/+] on Feb 26, 2025
mikehardy

mikehardy commented on Feb 26, 2025

@mikehardy
Collaborator

Hi there

  • could you use triple-backticks and language markers in the markdown so that's readable? I can't make much sense of the code
  • you are on an old version of react-native-firebase, make certain it reproduces in the current version
  • your posted code is not a minimum + complete example. Please post an App.tsx that is standalone and reproduces the problem

I've been testing this specific feature recently in response to an issue with the event firing after hot reloads and I saw no problem, so for me at least this doesn't reproduce when I inspect it myself - that means the App.tsx with a minimal + complete reproduction is critical to move forward on this issue. Please include exact steps (as if directing a kindergartner...) to reproduce any issue you see

https://github.com/mikehardy/rnfbdemo/blob/90889b436f602f280a733949991fbb5beb648079/App.tsx#L90-L94
https://github.com/mikehardy/rnfbdemo/blob/90889b436f602f280a733949991fbb5beb648079/App.tsx#L242-L255

KAMRONBEK

KAMRONBEK commented on Feb 27, 2025

@KAMRONBEK
Author

@mikehardy Hey bro, As you can see in the video, when I sign in, the app doesn’t automatically reload. That is, if I exit the app and come back, it shows that I’m already signed in. But during the sign-in process itself, this doesn’t happen. This issue occurs after building the APK — it also happens sometimes in the emulator or in debug mode. On iOS, though, it doesn’t happen, I did everything almost, but I have still this problem

recording.mp4

Navigator file
import React, { useContext, useEffect, useRef, useState } from 'react'
import analytics from '@react-native-firebase/analytics'
import Toast from 'react-native-toast-message'
import { OverflowMenuProvider } from 'react-navigation-header-buttons'
import RNBootSplash from 'react-native-bootsplash'
import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth'
import { NavigationContainer } from '@react-navigation/native'
import { AuthContext, UserFoundStates } from '../config/auth_context'
import { getUsersCountById } from '../api/firestore/get-users-by-id'
import PortalHost from '../components/portal/portal-host'
import AuthNavigator from './auth_navigator'
import RootNavigator from './root'
import { navRef } from './root_navigation_ref'
import { handleAppUpdates } from '../utils/app-update-handler'
import { UserContextProvider } from '../config/user_context'

const Navigator = () => {
const [initializing, setInitializing] = useState(true)
const { authUser, setAuthUser, userFound, setUserFound } =
useContext(AuthContext)
const routeNameRef = useRef()

useEffect(() => {
handleAppUpdates()
}, [])

useEffect(() => {
const handleAuthChange = (user: FirebaseAuthTypes.User | null) => {
setUserFound(UserFoundStates.InProgress)
setAuthUser(user ?? undefined)
}

return auth().onAuthStateChanged(handleAuthChange)
// eslint-disable-next-line react-hooks/exhaustive-deps

}, [])

useEffect(() => {
if (authUser) {
getUsersCountById(authUser.uid).then((count) => {
if (initializing) setInitializing(false)
if (count !== 0) {
setUserFound(UserFoundStates.Found)
} else {
setUserFound(UserFoundStates.NotFound)
}
})
} else {
setUserFound(UserFoundStates.NotFound)
if (initializing) setInitializing(false)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [authUser])

if (initializing) {
return null
}

return (

<NavigationContainer
ref={navRef}
onReady={() => {
routeNameRef.current = navRef.current?.getCurrentRoute().name
RNBootSplash.hide({ fade: true })
}}
onStateChange={async () => {
const previousRouteName = routeNameRef.current
const currentRouteName = navRef.current.getCurrentRoute().name

      if (previousRouteName !== currentRouteName) {
        await analytics().logScreenView({
          screen_name: currentRouteName,
          screen_class: currentRouteName,
        })
      }

      // Save the current route name for later comparison
      routeNameRef.current = currentRouteName
    }}>
    <OverflowMenuProvider>
      {userFound === UserFoundStates.Found ? (
        <UserContextProvider userId={authUser?.uid}>
          <RootNavigator />
        </UserContextProvider>
      ) : (
        <AuthNavigator />
      )}
    </OverflowMenuProvider>
    <Toast ref={(ref) => Toast.setRef(ref)} />
  </NavigationContainer>
</PortalHost>

)
}

export default Navigator

application file
import { ActionSheetProvider } from '@expo/react-native-action-sheet'
import analytics from '@react-native-firebase/analytics'
import '@react-native-firebase/storage'
import React from 'react'
import {
ActivityIndicator,
Platform,
StatusBar,
Text,
TextInput,
UIManager,
useColorScheme,
} from 'react-native'
// import codePush from 'react-native-code-push'
// import { Settings } from 'react-native-fbsdk-next'
import Geocoder from 'react-native-geocoding'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { enableScreens } from 'react-native-screens'
import { AuthContextProvider } from './src/config/auth_context'
import { FIREBASE_API_KEY } from './src/constants'
import Navigator from './src/navigation'

// Ask for consent first if necessary
// Possibly only do this for iOS if no need to handle a GDPR-type flow
// Settings.initializeSDK()

if (FIREBASE_API_KEY) {
Geocoder.init(FIREBASE_API_KEY)
}

if (DEV) {
// TODO: fix this ts error
// @ts-expect-error
import('./src/config/local-firebase')
}

if (DEV) {
const ga = analytics()
ga.setAnalyticsCollectionEnabled(false)
}

const defaultProps = {
maxFontSizeMultiplier: 1,
}

// fix facebook/react-native#30056
if (Platform.OS === 'android') {
// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof ActivityIndicator'
if (!ActivityIndicator.defaultProps) ActivityIndicator.defaultProps = {}
// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof ActivityIndicator'
ActivityIndicator.defaultProps.color = 'gray'
}

// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof Text'
Text.defaultProps = defaultProps

// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof TextInput'
TextInput.defaultProps = defaultProps
enableScreens()

// firebase.firestore().clearPersistence()
// firebase.firestore().settings({ persistence: false })
// firebase.firestore().disableNetwork()

if (
Platform.OS === 'android' &&
UIManager.setLayoutAnimationEnabledExperimental
) {
UIManager.setLayoutAnimationEnabledExperimental(true)
}

const App = () => {
const isDarkMode = useColorScheme() === 'dark'
return (
<GestureHandlerRootView style={{ flex: 1 }}>



<>
{Platform.select({ android: <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> })}

</>




)
}

// export default codePush({ checkFrequency: codePush.CheckFrequency.MANUAL })(App)
export default App

mikehardy

mikehardy commented on Feb 28, 2025

@mikehardy
Collaborator

Not a self contained, minimal reproduction

Post the simplest possible App.tsx that references zero other imports except react, react and react-native-firebase where you can demonstrate the problem

KAMRONBEK

KAMRONBEK commented on Mar 1, 2025

@KAMRONBEK
Author

@mikehardy this is App file.
Let me try to explain my issue clearly.

After building the APK and signing in, auth().onAuthStateChanged(onAuthStateChanged) does not trigger for some reason. Because of this, I had to manually log in by getting the currentUser from auth() and proceeding with authentication.

However, after logging in manually, any onSnapshot() listeners I use do not receive data. The real-time updates are not working. But if I close the app and reopen it, everything starts working fine, including onSnapshot().

This is the issue I’m facing, and I’m not sure what needs to be done to fix it. Any help would be appreciated!

import { ActionSheetProvider } from '@expo/react-native-action-sheet'
import analytics from '@react-native-firebase/analytics'
import '@react-native-firebase/storage'
import React from 'react'
import {
ActivityIndicator,
Platform,
StatusBar,
Text,
TextInput,
UIManager,
useColorScheme,
} from 'react-native'
// import codePush from 'react-native-code-push'
// import { Settings } from 'react-native-fbsdk-next'
import Geocoder from 'react-native-geocoding'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { enableScreens } from 'react-native-screens'
import { AuthContextProvider } from './src/config/auth_context'
import { FIREBASE_API_KEY } from './src/constants'
import Navigator from './src/navigation'

// Ask for consent first if necessary
// Possibly only do this for iOS if no need to handle a GDPR-type flow
// Settings.initializeSDK()

if (FIREBASE_API_KEY) {
Geocoder.init(FIREBASE_API_KEY)
}

if (DEV) {
// TODO: fix this ts error
// @ts-expect-error
import('./src/config/local-firebase')
}

if (DEV) {
const ga = analytics()
ga.setAnalyticsCollectionEnabled(false)
}

const defaultProps = {
maxFontSizeMultiplier: 1,
}

// fix facebook/react-native#30056
if (Platform.OS === 'android') {
// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof ActivityIndicator'
if (!ActivityIndicator.defaultProps) ActivityIndicator.defaultProps = {}
// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof ActivityIndicator'
ActivityIndicator.defaultProps.color = 'gray'
}

// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof Text'
Text.defaultProps = defaultProps

// @ts-ignore TS2339: Property 'defaultProps' does not exist on type 'typeof TextInput'
TextInput.defaultProps = defaultProps
enableScreens()

// firebase.firestore().clearPersistence()
firebase.firestore().settings({ persistence: false })
// firebase.firestore().disableNetwork()

if (
Platform.OS === 'android' &&
UIManager.setLayoutAnimationEnabledExperimental
) {
UIManager.setLayoutAnimationEnabledExperimental(true)
}

const App = () => {
const isDarkMode = useColorScheme() === 'dark'
return (
<GestureHandlerRootView style={{ flex: 1 }}>



<>
{Platform.select({ android: <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> })}

</>




)
}

// export default codePush({ checkFrequency: codePush.CheckFrequency.MANUAL })(App)
export default App

import analytics from '@react-native-firebase/analytics'
import { NavigationContainer } from '@react-navigation/native'
import React, { useContext, useRef } from 'react'
import RNBootSplash from 'react-native-bootsplash'
import Toast from 'react-native-toast-message'
import { OverflowMenuProvider } from 'react-navigation-header-buttons'
import { View, Text, ActivityIndicator } from 'react-native'
import PortalHost from '../components/portal/portal-host'
import { AuthContext, UserFoundStates } from '../config/auth_context'
import { UserContextProvider } from '../config/user_context'
import AuthNavigator from './auth_navigator'
import RootNavigator from './root'
import { navRef } from './root_navigation_ref'
import COLORS from '../config/colors'

const Navigator = () => {
const { authUser, userFound, initializing } = useContext(AuthContext)
const routeNameRef = useRef()

if (initializing) {
return null
}

return (

<NavigationContainer
ref={navRef}
onReady={() => {
routeNameRef.current = navRef.current?.getCurrentRoute()?.name
RNBootSplash.hide({ fade: true })
}}
onStateChange={async () => {
const previousRouteName = routeNameRef.current
const currentRouteName = navRef.current?.getCurrentRoute()?.name

      if (previousRouteName !== currentRouteName) {
        await analytics().logScreenView({
          screen_name: currentRouteName,
          screen_class: currentRouteName,
        })
      }

      // Save the current route name for later comparison
      routeNameRef.current = currentRouteName
    }}>
    <OverflowMenuProvider>
      <>
        {userFound === UserFoundStates.NotFound && <AuthNavigator />}
        {userFound === UserFoundStates.Found && (
          <UserContextProvider userId={authUser?.uid}>
            <RootNavigator />
          </UserContextProvider>
        )}
        {userFound === UserFoundStates.InProgress && (
          <View
            style={{
              flex: 1,
              justifyContent: 'center',
              alignItems: 'center',
              backgroundColor: COLORS.ERROR,
            }}>
            <Text
              style={{
                color: COLORS.BLACK,
                fontSize: 16,
                fontWeight: 'bold',
              }}>
              Loading...
            </Text>
            <ActivityIndicator size="large" color={COLORS.BLACK} />
          </View>
        )}
      </>
    </OverflowMenuProvider>
    <Toast ref={(ref) => Toast.setRef(ref)} />
  </NavigationContainer>
</PortalHost>

)
}

export default Navigator

mikehardy

mikehardy commented on Mar 1, 2025

@mikehardy
Collaborator

No, that's not a minimal complete example. Auth provider? Gesture handler? So much stuff. Pleas search "stackoverflow mcve" for a good guide. Reduce it to it's absolute bearest smallest essentials. A button to log in. Two text fields for username password. A handler fir the button to do the login. A callback for the auth changed event. Literally not one other thing. Please try that and if you still reproduce, post that file. Not a gigantic thing with unrelated items please

KAMRONBEK

KAMRONBEK commented on Mar 1, 2025

@KAMRONBEK
Author

import React from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';
import auth from '@react-native-firebase/auth';
import firestore from '@react-native-firebase/firestore';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
const App = () => {
  const [email, setEmail] = React.useState('group_creator@etalon.com');
  const [password, setPassword] = React.useState('password123');
  const [user, setUser] = React.useState(null);
  const [groups, setGroups] = React.useState([]);

  React.useEffect(() => {
    const subscriber = auth().onAuthStateChanged((currentUser) => {
      console.log('onAuthStateChanged triggered, user:', currentUser?.uid);
      setUser(currentUser);
      if (currentUser) {
        // Foydalanuvchi mavjud bo‘lganda guruhlarni olish
        fetchGroups(currentUser.uid);
      }
    });
    return subscriber;
  }, []);

  const fetchGroups = (uid) => {
    firestore()
      .collection('groups')
      .where('users', 'array-contains', uid)
      .onSnapshot(
        (snapshot) => {
          console.log('onSnapshot triggered, groups:', snapshot.docs.length);
          const groupList = snapshot.docs.map(doc => ({
            id: doc.id,
            ...doc.data(),
          }));
          setGroups(groupList);
        },
        (error) => {
          console.error('Firestore xatosi:', error);
        },
      );
  };

  const onLoginPress = async () => {
    try {
      await auth().signInWithEmailAndPassword(email, password);
      // Agar onAuthStateChanged ishlamasa, qo‘ldan tekshirish
      const currentUser = auth().currentUser;
      if (currentUser) {
        setUser(currentUser);
        fetchGroups(currentUser.uid);
      }
    } catch (error) {
      alert('Login error:' + error.message);
    }
  };

  return (
    <GestureHandlerRootView style={styles.container}>
      <SafeAreaProvider>
        <View style={styles.container}>
          <Text style={styles.title}>Login</Text>
          <TextInput
            style={styles.input}
            placeholder="Email"
            value={email}
            onChangeText={setEmail}
            autoCapitalize="none"
          />
          <TextInput
            style={styles.input}
            placeholder="Password"
            value={password}
            onChangeText={setPassword}
            secureTextEntry
            autoCapitalize="none"
          />
          <Button title="Login" onPress={onLoginPress} />
          {user ? (
            <Text style={styles.userText}>Logged in as: {user.email}</Text>
          ) : null}
          <Text style={styles.groupsTitle}>Your Groups:</Text>
          {groups.map((group) => (
            <Text key={group.id} style={styles.groupText}>
              {group.groupName || 'No name'}
            </Text>
          ))}
        </View>
      </SafeAreaProvider>
    </GestureHandlerRootView>
  );
};

export default App;

12 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mikehardy@pierroo@KAMRONBEK@jonaslarsson-ou

        Issue actions

          auth().onAuthStateChanged does not always trigger after sign-in on Android in React Native 0.77 · Issue #8374 · invertase/react-native-firebase