Skip to content

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

Open
@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:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions