typescript – React Native iOS – Firebase Anonymous Authentication Error: [auth/internal-error] An internal error has occurred, please try again


We got multiple [auth/internal-error] An internal error has occurred, please try again error by using auth().signInAnonymously() on the Production environment. You can find the related GitHub issue here: https://github.com/invertase/react-native-firebase/issues/7511 (Mixpanel Logs and a more detailed description can be found.)

It is very confusing that there is only less than 5% of users experience this issue only in production.


Problem

A portion (5%) of our users are encountering an [auth/internal-error] when attempting to authenticate anonymously with Firebase.

The application’s Firebase authentication has been set up following the official documentation at https://rnfirebase.io/auth/usage. We have two separate Firebase projects for Development and Production. They use the same bundle identifier but separated GoogleService-Info.plist files. (As you can see in AppDelegate.mm)


Additional Notes

Successful Cases: It’s noteworthy that a majority of users can authenticate without any issues.

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.


Interesting Cases

Some of our users were able to authenticate with signInAnonymously after several retries (We have a retry button appearing after this internal error happens).
Some of our users have closed the app after the signInAnonymously error and re-opened the app after several hours – they do not have any issues with authentication anymore.


Background

  • Connected with the GCP team, and they inspected the GCP logs in-depth. However, no GCP server errors were logged by the Identity Toolkit.

  • We have been unable to reproduce this issue with any iOS Testing device, both in development and production environments.

  • Removed AppCenter and CodePush from the project to check for any conflicts, but it made no difference.

  • Users in Germany have been experiencing this auth/internal-error most frequently.

  • The majority of users cannot authenticate successfully again after experiencing an auth/internal-error. Some of them can successfully authenticate after retrying 20 times or reopening the app one day later.

  • The majority of users can authenticate successfully if they encounter the auth/network-request failed error.


Files

Sharing App.tsx – package.json – Podfile and AppDelegate contents below.

// 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, navigation 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()
  }, [])
// package.json

...
"@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",
...
// Podfile

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 '....' 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}/.."
  )

  target '.....' 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.mm
#import "AppDelegate.h"
#import "RNBootSplash.h"
#import <Firebase.h>
#import <React/RCTBundleURLProvider.h>
#import <AppsFlyerLib/AppsFlyerLib.h>
#import <AppsFlyerAttribution.h>

#import <AuthenticationServices/AuthenticationServices.h>
#import <SafariServices/SafariServices.h>
#import <FBSDKCoreKit/FBSDKCoreKit-Swift.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // Here is where we pick from Production and Development GoogleService-Info.plist
  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 = @"....";
  // 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 [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#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

We are expecting none of our users experience this [auth/internal-error] An internal error has occurred, please try again error.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img