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.