Skip to content

[🐛] auth.PhoneAuthProvider.credential is undefined on IOS release build #8444

Open
@tux2nicolae

Description

@tux2nicolae

Issue

Just noticed our phone authentication does not work anymore (only on release builds), it seems very very similar to this issue

#8315

More specifically when calling auth.PhoneAuthProvider.credential

Image

Project Files

Javascript

Click To Expand

import auth, {
  FirebaseAuthTypes,
  getAuth,
  signInWithCredential,
  verifyPhoneNumber,
} from '@react-native-firebase/auth';
import React, {useCallback} from 'react';
import {UNKNOWN_ERROR} from '../../shared/utils/translateError';

const AUTOVERIFY_TIME = 10;
const RESEND_DELAY = 30;

export const useFirebasePhoneAuth = (phoneNumber: string) => {
  const [canResend, setCanResend] = React.useState(false);

  const timerRef = React.useRef<NodeJS.Timeout | null>(null);

  const phoneAuthSnapshotRef =
    React.useRef<FirebaseAuthTypes.PhoneAuthSnapshot | null>(null);

  const startResendTimer = useCallback(() => {
    setCanResend(false);

    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }

    timerRef.current = setTimeout(
      () => setCanResend(true),
      RESEND_DELAY * 1000,
    );
  }, [setCanResend]);

  const sendCode = useCallback(
    async (force: boolean) => {
      startResendTimer();

      phoneAuthSnapshotRef.current =
        await new Promise<FirebaseAuthTypes.PhoneAuthSnapshot>(
          (resolve, reject) => {
            verifyPhoneNumber(
              getAuth(),
              phoneNumber,
              AUTOVERIFY_TIME,
              force,
            ).on(
              'state_changed',
              phoneAuthSnapshot => {},
              error => {
                reject(error);
              },
              phoneAuthSnapshot => {
                resolve(phoneAuthSnapshot);
              },
            );
          },
        );

      // try auto retrieve the code on android
      if (phoneAuthSnapshotRef.current.code) {
        return phoneAuthSnapshotRef.current.code;
      }
    },
    [phoneNumber, startResendTimer],
  );

  const authenticateWithCode = useCallback(
    async (code: string) => {
      if (!phoneAuthSnapshotRef.current) {
        throw {code: UNKNOWN_ERROR};
      }

      const credential = auth.PhoneAuthProvider.credential(
        phoneAuthSnapshotRef.current.verificationId,
        code,
      );

      let userCredential: FirebaseAuthTypes.UserCredential | null = null;

      // Upgrading current anonymous user has some limitations, please check :
      // https://github.com/firebase/flutterfire/issues/6006
      // https://github.com/firebase/flutterfire/issues/3949
      //
      // We can't use linkWithCredential because if an user already exists
      // with that specific phone number we will get a session expired exception
      // and will be forced to resend a new SMS code
      //
      // const {currentUser} = firebase.auth();
      // if (currentUser && currentUser.isAnonymous) {
      //   try {
      //     userCredential = await currentUser.linkWithCredential(credential);
      //   } catch (error) {
      //     console.log(error);
      //   }
      // }

      if (!userCredential) {
        userCredential = await signInWithCredential(getAuth(), credential);
      }

      return userCredential.user;
    },
    [phoneAuthSnapshotRef],
  );

  // proper cleanup on unmount
  React.useEffect(() => {
    return () => {
      timerRef.current && clearTimeout(timerRef.current);
    };
  }, []);

  return {sendCode, authenticateWithCode, canResend};
};

package.json:

  "dependencies": {
    // if you need more please let me know
    "@react-native-firebase/analytics": "^21.13.0",
    "@react-native-firebase/app": "^21.13.0",
    "@react-native-firebase/auth": "^21.13.0",
    "@react-native-firebase/messaging": "^21.13.0",
    "react-native": "0.78.2",
  }
  "devDependencies": {
    "@babel/core": "^7.26.10",
    "@babel/preset-env": "^7.26.9",
    "@babel/runtime": "^7.27.0",
    "@react-native-community/cli": "15.1.3",
    "@react-native-community/cli-platform-android": "15.1.3",
    "@react-native-community/cli-platform-ios": "15.1.3",
    "@react-native/babel-preset": "0.78.2",
    "@react-native/eslint-config": "0.78.2",
    "@react-native/metro-config": "0.78.2",
    "@react-native/typescript-config": "0.78.2",
    "@types/jest": "^29.5.14",
    "@types/react": "^19.1.0",
    "@types/react-native-vector-icons": "^6.4.18",
    "@types/react-test-renderer": "^19.1.0",
    "eslint": "^8.57.1",
    "jest": "^29.7.0",
    "patch-package": "^8.0.0",
    "react-test-renderer": "19.0.0",
    "typescript": "^5.8.2"
  },

firebase.json for react-native-firebase v6:

{
  "react-native": {
    "messaging_ios_auto_register_for_remote_messages": true
  }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
ENV['RCT_NEW_ARCH_ENABLED'] = '0'

def node_require(script)
  # Resolve script with node to allow for hoisting
  require Pod::Executable.execute_command('node', ['-p',
    "require.resolve(
      '#{script}',
      {paths: [process.argv[1]]},
    )", __dir__]).strip
end

node_require('react-native/scripts/react_native_pods.rb')

platform :ios, min_ios_version_supported
prepare_react_native_project!

use_frameworks! :linkage => :static

$RNFirebaseAsStaticFramework = true
$RNFirebaseAnalyticsWithoutAdIdSupport = true

target 'Menoo' do
  config = use_native_modules!(packages_to_skip: ['react-native-compressed-jsbundle'])

  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes should be disabled in AppClip due to size constraints
    # Be aware that "export USE_HERMES=false" is also set in .xcode.env
    :hermes_enabled => false,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )
end

AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSLog(@"Menoo");

  [FIRApp configure];

  self.moduleName = @"Menoo";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  
  NSDictionary *initProps = [self prepareInitialProps];
  // this is for passing isHeadless parameter
  // https://rnfirebase.io/messaging/usage
  NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:initProps withLaunchOptions:launchOptions];
  
  self.initialProps = appProperties;
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}


Android

Click To Expand

Have you converted to AndroidX?

  • my application is an AndroidX application?
  • I am using android/gradle.settings jetifier=true for Android compatibility?
  • I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->


Environment

Click To Expand

react-native info output:

System:
  OS: macOS 14.5
  CPU: (8) arm64 Apple M1
  Memory: 72.11 MB / 8.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.20.4
    path: ~/.nvm/versions/node/v18.20.4/bin/node
  Yarn: Not Found
  npm:
    version: 10.7.0
    path: ~/.nvm/versions/node/v18.20.4/bin/npm
  Watchman:
    version: 2024.08.26.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java: Not Found
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.1.3
    wanted: 15.1.3
  react:
    installed: 19.0.0
    wanted: 19.0.0
  react-native:
    installed: 0.78.2
    wanted: 0.78.2
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: false
  newArchEnabled: false
  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • 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:
    • 21.13.0
  • Firebase module(s) you're using that has the issue:
    • e.g. Instance ID
  • Are you using TypeScript?
    • Y/N & VERSION


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