react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

[🐛] 🔥 expo SDK53 appCheck plugin issue in iOS causes appCheck/token-error

Open tm00-git opened this issue 8 months ago • 7 comments

Issue

This is thrown [Error: [appCheck/token-error] The operation couldn’t be completed. The attestation provider DeviceCheckProvider is not supported on current platform and OS version.] upon appCheck initialisation.


Official Documentation https://rnfirebase.io/app-check/usage Indicate that file ios/ProjectName/AppDelegate.swift needs to be modified as follows: +RNFBAppCheckModule.sharedInstance() // <-- new for AppCheck to work +FirebaseApp.configure() // <-- From App/Core integration

however, @react-native-firebase/app-check plugin for expo generates: // @generated begin @react-native-firebase/app-check - expo prebuild (DO NOT MODIFY) FirebaseApp.configure() RNFBAppCheckModule.sharedInstance() // @generated end @react-native-firebase/app-check

Looks like the sequence is mixed what causes error. Upon manually correcting the sequence as per documentation in the AppDelegate.swift appCheck does work.

Project Files

Javascript

Click To Expand

package.json:

{
  "dependencies": {
    "@react-native-firebase/app": "^22.2.0",
    "@react-native-firebase/app-check": "^22.2.0",
    "@react-native-firebase/auth": "^22.2.0",
    "@react-native-firebase/firestore": "^22.2.0",
    "@react-native-firebase/functions": "^22.2.0",
    "@react-native-firebase/storage": "^22.2.0",
    "@react-navigation/native": "^7.0.14",
    "expo": "^53.0.9",
    "expo-application": "~6.1.4",
    "expo-blur": "~14.1.4",
    "expo-build-properties": "~0.14.6",
    "expo-constants": "^17.1.6",
    "expo-dev-client": "~5.1.8",
    "expo-font": "~13.3.1",
    "expo-haptics": "~14.1.4",
    "expo-image": "~2.1.7",
    "expo-linking": "~7.1.5",
    "expo-localization": "~16.1.5",
    "expo-location": "~18.1.5",
    "expo-router": "~5.0.7",
    "expo-splash-screen": "~0.30.8",
    "expo-status-bar": "~2.2.3",
    "expo-symbols": "~0.4.4",
    "expo-system-ui": "~5.0.7",
    "expo-web-browser": "~14.1.6",
    "geofire-common": "^6.0.0",
    "react": "19.0.0",
    "react-dom": "19.0.0",
    "react-hook-form": "^7.53.0",
    "react-native": "0.79.2",
    "react-native-gesture-handler": "~2.24.0",
    "react-native-reanimated": "~3.17.4",
    "react-native-safe-area-context": "5.4.0",
    "react-native-screens": "~4.10.0",
    "react-native-web": "^0.20.0",
    "react-native-webview": "13.13.5",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/humanize-duration": "^3.27.4",
    "@types/jest": "^29.5.12",
    "@types/lodash": "^4.17.16",
    "@types/murmurhash3js": "^3.0.7",
    "@types/react": "~19.0.10",
    "eslint": "^9.27.0",
    "eslint-config-expo": "^9.2.0",
    "eslint-config-prettier": "^10.1.5",
    "eslint-plugin-prettier": "^5.4.0",
    "jest": "^29.2.1",
    "jest-expo": "~53.0.5",
    "prettier": "^3.5.3",
    "typescript": "~5.8.3",
    "typescript-eslint": "^8.32.1"
  },
}

iOS

Click To Expand

ios/Podfile:

  • [x ] I'm not using Pods
  • [] I'm using Pods and my Podfile looks like:
# N/A

AppDelegate.swift:

import Expo
import FirebaseCore
import RNFBAppCheck
import React
import ReactAppDependencyProvider

// @generated begin react-native-maps-import - expo prebuild (DO NOT MODIFY) sync-bee50fec513f89284e0fa3f5d935afdde33af98f
#if canImport(GoogleMaps)
import GoogleMaps
#endif
// @generated end react-native-maps-import
@UIApplicationMain
public class AppDelegate: ExpoAppDelegate {
  var window: UIWindow?

  var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
  var reactNativeFactory: RCTReactNativeFactory?

  public override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    let delegate = ReactNativeDelegate()
    let factory = ExpoReactNativeFactory(delegate: delegate)
    delegate.dependencyProvider = RCTAppDependencyProvider()

    reactNativeDelegate = delegate
    reactNativeFactory = factory
    bindReactNativeFactory(factory)

#if os(iOS) || os(tvOS)
    window = UIWindow(frame: UIScreen.main.bounds)
// @generated begin @react-native-firebase/app-check - expo prebuild (DO NOT MODIFY) sync-1b64bf073a4e4499902c67fac34bb79f99417bdc
    FirebaseApp.configure()
    RNFBAppCheckModule.sharedInstance()
// @generated end @react-native-firebase/app-check
    factory.startReactNative(
      withModuleName: "main",
      in: window,
      launchOptions: launchOptions)
#endif

// @generated begin react-native-maps-init - expo prebuild (DO NOT MODIFY) sync-e0ef77e269046054abb8a668c1b5e1674df3c01a
#if canImport(GoogleMaps)
GMSServices.provideAPIKey("---")
#endif
// @generated end react-native-maps-init
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  // Linking API
  public override func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
  ) -> Bool {
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
    return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
  }

  // Universal Links
  public override func application(
    _ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
  ) -> Bool {
    let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
  }
}

class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
  // Extension point for config-plugins

  override func sourceURL(for bridge: RCTBridge) -> URL? {
    // needed to return the correct URL for expo-dev-client.
    bridge.bundleURL ?? bundleURL()
  }

  override func bundleURL() -> URL? {
#if DEBUG
    return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
#else
    return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
  }
}


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:

 OUTPUT GOES HERE
  • Platform that you're experiencing the issue on:
    • [x] 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:
    • 22.2.0
  • Firebase module(s) you're using that has the issue:
    • initializeAppCheck
  • Are you using TypeScript?
    • Y 5.8.3

tm00-git avatar May 21 '25 21:05 tm00-git

Hello @johnbonds, we are looking into this and will get back to you as soon as we have an update

ahmedhamouda78 avatar Jun 16 '25 15:06 ahmedhamouda78

Hi @johnbonds, unfortunately Cognito does not support modifying the length of the OTP at the moment. We will reassess this feature-request if Cognito adds support for OTP length configuration and update this issue accordingly.

soberm avatar Jul 01 '25 09:07 soberm

Hi @johnbonds, unfortunately Cognito does not support modifying the length of the OTP at the moment. We will reassess this feature-request if Cognito adds support for OTP length configuration and update this issue accordingly.

Curious, why enforce the 8 digit PIN?

I would also like to customize the length of the PIN. E.g 4 or 6.

Was there any progress, is there an ETA?

Odas0R avatar Sep 02 '25 00:09 Odas0R

Curious, why enforce the 8 digit PIN?

Amplify does not enforce the 8 digit PIN. it is on Cognito side, for more details please check Cognito documentations. Will close this ticket as this is a limitation on Cognito side. please do not hesitate to reopen it if you have additional questions.

osama-rizk avatar Sep 02 '25 15:09 osama-rizk