invertase / react-native-firebase

πŸ”₯ A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.6k stars 2.19k forks source link

πŸ”₯ [πŸ›] Critical Issue with Firebase Anonymous Authentication: [auth/internal-error] An internal error has occurred, please try again. #7511

Closed denizmersinlioglu closed 6 months ago

denizmersinlioglu commented 8 months ago

Issue

We got multiple [auth/internal-error] An internal error has occurred, please try again error by using auth().signInAnonymously().

Description

Problem: Approximately a portion of our users are encountering an [auth/internal-error] when attempting to authenticate anonymously with Firebase. Impact: This is a critical issue for our project since our application's functionality heavily relies on Firebase authentication. The problem is preventing a significant portion of users from accessing key features of the application.

Current Implementation: Details: Our application's Firebase authentication has been set up in accordance with the official documentation.

Additional Notes: Successful Cases: It's noteworthy that a majority of users are able to authenticate without any issues. πŸ”₯ Urgency: Given the substantial impact on user experience and functionality, resolving this issue is of high priority.

Specific Conditions: πŸ”₯ User Count Spike Correlation: The error is notably more frequent during times when our user count spikes, suggesting a possible issue with handling high concurrent authentication requests. Successful Authentication: Despite this issue, majority of users are able to authenticate successfully under normal conditions.

Urgency and Request for Assistance: Criticality: Addressing this issue is crucial due to its significant impact on user experience and app functionality during peak times. Request for Insights: We are seeking insights or suggestions on how to mitigate this issue, especially under high user load conditions.


Project Files

  // App.tsx
  useEffect(() => {
    const subscriber = auth().onAuthStateChanged(async user => {
      if (initializing) {
        setTimeout(() => RNBootSplash.hide({ fade: true }), 300)
        setInitializing(false)
      }

      if (user) //  Do some configuration
    })

    return () => {
      subscriber()
    }
  }, [])

 if (initializing) return null // render nothing until firebase auth is initialized.

 // Wrappers are redux, persistor, styled-components theme provider etc...
 return <Wrappers> <AppContent /> </Wrappers>
  // AppContent.tsx
  useEffect(() => {
    const configureAuthUser = async () => {
      try {
        const result = await auth().signInAnonymously()
        const user = result.user
        if (user) {
          dispatch(fetchMeUser())
          analytics.track(events.app.authentication_success(user.uid))
        } else {
          analytics.report('user is null in app configure auth user')
          analytics.track(events.app.authentication_user_null())
        }
      } catch (error: any) {
        analytics.report('error configuring auth user: ' + error.message)
        analytics.track(events.app.authentication_failed(error.message))
      }
    }

    configureAuthUser()
  }, [])

Javascript

Click To Expand

#### `package.json`: ```json { "name": "OurApp", "version": "2.0.0", "private": true, "scripts": { "dist:ios:appstore": "cd ./scripts && ./ios-dist-appstore.sh", "dist:ios:adhoc": "cd ./scripts && ./ios-dist-adhoc.sh", "prepare": "patch-package", "android": "react-native run-android", "android:release": "react-native run-android --variant=release", "android:build": "cd android && ./gradlew assembleRelease", "android:bundle": "cd android && ./gradlew bundleRelease", "ios": "react-native run-ios", "start": "react-native start", "test": "jest", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "link:assets": "npx react-native-asset", "watch": "yarn tsc -- --watch", "patch": "npx patch-package", "pretty": "prettier --config .prettierrc.js './src/**/*.{ts,tsx}' --write", "postinstall": "react-native setup-ios-permissions", "codepush:ios": "appcenter codepush release-react -a ....... -d Production", "codepush:android": "appcenter codepush release-react -a ....... -d Production", "codepush:all": "yarn codepush:ios && yarn codepush:android" }, "dependencies": { "@gorhom/bottom-sheet": "^4.4.6", "@react-native-camera-roll/camera-roll": "^6.0.0", "@react-native-community/blur": "^4.3.2", "@react-native-community/slider": "^4.4.3", "@react-native-firebase/analytics": "^18.7.2", "@react-native-firebase/app": "^18.7.2", "@react-native-firebase/auth": "^18.7.2", "@react-native-firebase/crashlytics": "^18.7.2", "@react-native-firebase/database": "^18.7.2", "@react-native-firebase/messaging": "^18.7.2", "@react-native-firebase/storage": "^18.7.2", "@react-native-masked-view/masked-view": "0.2.9", "@react-native-seoul/masonry-list": "^1.4.2", "@react-navigation/bottom-tabs": "^6.3.2", "@react-navigation/native": "^6.0.11", "@react-navigation/native-stack": "^6.7.0", "appcenter": "^5.0.0", "i18next": "^22.4.14", "immer": "^9.0.21", "lodash": "^4.17.21", "lottie-react-native": "^6.2.0", "mixpanel-react-native": "^2.3.1", "moment": "^2.29.4", "react": "18.2.0", "react-i18next": "^11.18.1", "react-native": "0.71.8", "react-native-appsflyer": "^6.12.2", "react-native-bootsplash": "^4.3.2", "react-native-circular-progress-indicator": "^4.4.2", "react-native-code-push": "^8.1.0", "react-native-device-info": "^10.12.0", "react-native-face-detection": "^0.1.1", "react-native-fast-image": "^8.5.11", "react-native-fbsdk-next": "^12.1.2", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "^2.9.0", "react-native-get-random-values": "^1.9.0", "react-native-haptic-feedback": "^1.14.0", "react-native-image-picker": "^7.0.3", "react-native-image-resizer": "^1.4.5", "react-native-inappbrowser-reborn": "^3.7.0", "react-native-linear-gradient": "^2.6.2", "react-native-mmkv": "^2.8.0", "react-native-pager-view": "^6.2.2", "react-native-permissions": "^3.10.1", "react-native-purchases": "^6.2.3", "react-native-rate": "^1.2.12", "react-native-reanimated": "^2.14.4", "react-native-reanimated-carousel": "^3.5.1", "react-native-safe-area-context": "^4.5.1", "react-native-screens": "^3.15.0", "react-native-share": "^9.4.1", "react-native-svg": "^12.4.3", "react-native-tab-view": "^3.5.2", "react-native-toast-message": "^2.1.7", "react-native-video": "^5.2.1", "react-redux": "^8.0.5", "recyclerlistview": "^4.2.0", "redux": "^4.2.0", "redux-persist": "^6.0.0", "redux-thunk": "^2.4.2", "styled-components": "^5.3.5", "uuid": "^9.0.0" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native-community/eslint-config": "^3.2.0", "@react-native/metro-config": "^0.72.11", "@tsconfig/react-native": "^2.0.2", "@types/jest": "^29.2.1", "@types/lodash": "^4.14.182", "@types/react": "^18.0.24", "@types/react-native-background-timer": "^2.0.0", "@types/react-test-renderer": "^18.0.0", "@types/styled-components": "5.1.6", "@types/uuid": "^9.0.1", "babel-jest": "^29.2.1", "eslint": "^8.19.0", "jest": "^29.2.1", "metro-react-native-babel-preset": "0.73.9", "patch-package": "^6.4.7", "prettier": "^2.4.1", "react-native-svg-transformer": "^1.0.0", "react-test-renderer": "18.2.0", "typescript": "4.8.4" }, "jest": { "preset": "react-native" }, "reactNativePermissionsIOS": [ "AppTrackingTransparency", "PhotoLibrary", "Notifications" ] } ``` #### `firebase.json` for react-native-firebase v6: ```json { "react-native": { "crashlytics_debug_enabled": true, "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": true, "google_analytics_automatic_screen_reporting_enabled": false, "analytics_auto_collection_enabled": true, "android_task_executor_maximum_pool_size": 10, "android_task_executor_keep_alive_seconds": 3 } } ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' platform :ios, '13' prepare_react_native_project! inhibit_all_warnings! use_frameworks! :linkage => :static target 'OurApp' do use_modular_headers! config = use_native_modules! flags = get_default_flags() $RNFirebaseAsStaticFramework = true pod 'MLKitCommon', :podspec => 'MLKitCommon.podspec.json' pod 'MLKitVision', :podspec => 'MLKitVision.podspec.json' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec', :modular_headers => false use_react_native!( :path => config[:reactNativePath], :hermes_enabled => flags[:hermes_enabled], :fabric_enabled => flags[:fabric_enabled], :app_path => "#{Pod::Config.instance.installation_root}/.." ) pod 'CocoaImageHashing', :git => 'https://github.com/ameingast/cocoaimagehashing.git' target 'OurAppTests' do inherit! :complete # Pods for testing end post_install do |installer| react_native_post_install( installer, :mac_catalyst_enabled => false ) __apply_Xcode_12_5_M1_post_install_workaround(installer) installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = "" config.build_settings['CODE_SIGNING_REQUIRED'] = "NO" config.build_settings['CODE_SIGNING_ALLOWED'] = "NO" end end end end ``` #### `AppDelegate.m`: ```objc #import "AppDelegate.h" #import "RNBootSplash.h" #import #import #import #import #import #import #import #import @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSString *filePath; #ifdef DEBUG NSLog(@"[FIREBASE] Development mode."); filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:@"Development"]; #else NSLog(@"[FIREBASE] Production mode."); filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:@"Production"]; #endif FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath]; [FIRApp configureWithOptions:options]; [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; [FBSDKApplicationDelegate.sharedInstance initializeSDK]; self.moduleName = @"OurApp"; // You can add your custom initial props in the dictionary below. // They will be passed down to the ViewController used by React Native. self.initialProps = @{}; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [CodePush bundleURL]; #endif } /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. /// /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { return true; } - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps { UIView *rootView = [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps]; [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView]; // ⬅️ initialize the splash screen return rootView; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [[AppsFlyerLib shared] registerUninstall:deviceToken]; } // Deep linking // Open URI-scheme for iOS 9 and above - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *) options { [[AppsFlyerAttribution shared] handleOpenUrl:url options:options]; return YES; } // Open Universal Links - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable)) restorationHandler { [[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler]; return YES; } @end ```

Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 13.4.1 CPU: (10) arm64 Apple M1 Pro Memory: 61.36 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.15.0 - ~/.nvm/versions/node/v16.15.0/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v16.15.0/bin/yarn npm: 8.5.5 - ~/.nvm/versions/node/v16.15.0/bin/npm Watchman: 2023.10.09.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.12.1 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 Android SDK: Not Found IDEs: Android Studio: 2022.1 AI-221.6008.13.2211.9619390 Xcode: 14.2/14C18 - /usr/bin/xcodebuild Languages: Java: 11.0.18 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.8 => 0.71.8 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **Platform that you're experiencing the issue on**: - [X] iOS - [ ] Android - [X] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - `18.7.2` - **`Firebase` module(s) you're using that has the issue:** - `Authentication` - **Are you using `TypeScript`?** - `Yes 4.8.4`

denizmersinlioglu commented 8 months ago

Here is a more detailed event log for the user who experienced this error. As you can see, it occurred immediately after the user first opened the application.

Screenshot 2023-12-15 at 02 00 47

When the user encounters this issue, we have implemented a covering mechanism that displays an alert on the home screen, prompting them to retry authentication with Firebase.

Screenshot 2023-12-15 at 02 00 00
denizmersinlioglu commented 8 months ago

Some of our users are quite persistent. After struggling for 20-30 seconds, they reopen the application and attempt authentication multiple times. Eventually, they are able to authenticate successfully. (After so many attempts and 30 seconds from First Open)

Screenshot 2023-12-15 at 02 01 43
denizmersinlioglu commented 8 months ago

Note that all the logs belong to the same user; we can use timestamps as a reference. When I checked, it took 50 seconds for the user to successfully authenticate with Firebase.

We also have an ongoing email exchange with the Firebase Team. We have investigated all GCP logs of the Identity API together. While they have not identified any specific issue yet, they are continuing with their investigation.

denizmersinlioglu commented 8 months ago

Here is another user with no authentication problem. As you can see it takes 3 seconds to successfully authenticate.

Screenshot 2023-12-15 at 02 13 10
mikehardy commented 8 months ago

πŸ€” sorry about the delay looking into this - I saw it when it came in but did not have any specific insight, just ideas for more data

I think pursuing it with the GCP folks is a good idea - if most users are able to auth and even users with problems are able to auth, doesn't that seem like the software at the client side (device operating system, application, react-native-firebase, firebase native SDK...) is performing well

Some thoughts - all hypothetical

Sorry there's no concrete suggestion like "oh try this it will fix it..." but perhaps something like the above will turn up something. The most likely thing (not a definite in any way, just most likely) is GCP throttling somehow for some reason, based on it working mostly, working for people that do have problems eventually, and correlation with user count spikes

hayata-suenaga commented 8 months ago

I also got the same error with auth().signInWithCustomToken(token) when running a React Native app in the dev environment.

[auth/internal-error] An internal error has occurred, please try again.
mikehardy commented 8 months ago

@hayata-suenaga do you see anything in the native device logs with the device running the app plugged in to your development machine?

denizmersinlioglu commented 8 months ago

We have enabled Google Authentication in the Firebase console, so our GoogleService-Info.plist file contains the client_id and reversed_client_id. However, Google is not actively used in our project, and the reversed_client_id has not been added to the URL Schemas in Xcode. I'm unsure if this is related to the issue.

@mikehardy we attempted to manually modify the GoogleService-Info.plist. Upon altering the API key, we encountered an internal error. I suspect there's an issue with the Firebase configuration, leading to the library throwing an auth/internal error.

mikehardy commented 8 months ago

we attempted to manually modify the GoogleService-Info.plist.

@denizmersinlioglu I would not attempt this - I don't think it has ever been needed in any use cases I'm aware of ? I would always just download fresh versions of the plist and json (for ios and android...) and use them

denizmersinlioglu commented 8 months ago

we attempted to manually modify the GoogleService-Info.plist.

@denizmersinlioglu I would not attempt this - I don't think it has ever been needed in any use cases I'm aware of ? I would always just download fresh versions of the plist and json (for ios and android...) and use them

@mikehardy We attempted to change the API key for testing purposes to gain insights about the issue. As far as we understand, internal error thrown when something wrong with firebase configuration process.

In production, we use an unmodified version of the .plist file.

Could this be related to the Google Sign-In method?

I still can't understand how it's possible to have this issue in production and affect only 5% of our users. πŸ€”

mikehardy commented 8 months ago

I have noticed firebase (and GCP in general) dies not like VPNs. Perhaps 5% of your users are on VPNs? I am guessing only, small chance of this being a correct guess

denizmersinlioglu commented 8 months ago

It's highly unlikely to encounter so many VPN errors. πŸ€”

We are using two Firebase projects with the same bundle ID. We configured the production and development .plist files using AppDelegate macros.

Could this error be somehow related to the Firebase configuration? How can we inspect this error further?

mikehardy commented 8 months ago

@denizmersinlioglu -->

do you see anything in the native device logs with the device running the app plugged in to your development machine?

denizmersinlioglu commented 8 months ago

@mikehardy unfortunately no. We have tested the signInAnonymously method by creating more than 200 users in the development environment and have not observed any logs or errors.

github-actions[bot] commented 7 months ago

Hello πŸ‘‹, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.