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.66k stars 2.21k forks source link

[🐛] App Check - Firestore permission denied after updating app through TestFlight #7810

Closed fransoudelaar closed 1 month ago

fransoudelaar commented 4 months ago

The app fails on first launch after updating through TestFlight or after first install through TestFlight due to a Firestore permission issue.

Non-fatal Exception: JavaScriptError
[firestore/permission-denied] The caller does not have permission to execute the specified operation.

We are using an Enforced Firestore together with App Check. Configured Device Check and App Attest for iOS and Play Integrity for Android.

  1. In the app we initialise App check first:
    const appCheck = firebase.appCheck();

    const rnfbProvider = appCheck.newReactNativeFirebaseAppCheckProvider();

    rnfbProvider.configure(
      __DEV__
        ? {
            android: {
              provider: 'debug',
              debugToken: '62D1ABF2-36EF-4A88-88EB-17C9EE5EB07C',
            },
            apple: {
              provider: 'debug',
              debugToken: Environment.EXPO_PUBLIC_APPCHECK_DEBUG_TOKEN_IOS,
            },
          }
        : {
            android: {
              provider: 'playIntegrity',
            },
            apple: {
              provider: 'appAttestWithDeviceCheckFallback',
            },
          },
    );

    crashlytics().log(`Init App Check.`);

    await appCheck.initializeAppCheck({
      provider: rnfbProvider,
      isTokenAutoRefreshEnabled: true,
    });
  1. And do a Firestore request after:

const data = (await firestore().collection('name').doc('name').get()).data()

  1. If it fails, and it always fails on first launch after updating the app, we try to get the token with forceRefresh enabled:

const { token } = await firebase.appCheck().getToken(true);

  1. After we received a valid token we do the Firestore request from step 2 again but it returns the same error. See screenshot from Logs & Breadcrumbs in Crashlytics below(read from bottom to top):

Screenshot 2024-05-28 at 14 15 57

There is a valid token but Firestore is not using it somehow.

package.json:

{
  "dependencies": {
    ...
    "@react-native-firebase/analytics": "^20.0.0",
    "@react-native-firebase/app": "^20.0.0",
    "@react-native-firebase/app-check": "^20.0.0",
    "@react-native-firebase/crashlytics": "^20.0.0",
    "@react-native-firebase/firestore": "^20.0.0",
    ...
    "expo": "~51.0.7",
    "expo-build-properties": "~0.12.1",
    "expo-dev-client": "~4.0.14",
    "expo-router": "~3.5.14",
    "expo-splash-screen": "~0.27.4",
    "expo-status-bar": "~1.12.1",
    ...
    "react": "18.2.0",
    "react-native": "0.74.1",
    ...
  }
}

firebase.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
    }
}
mikehardy commented 3 months ago

is this still happening after release of v20.1.0 here with updated SDKs from PR #7820 ?

fransoudelaar commented 3 months ago

Unfortunately it's still happening after upgrading to v20.1.0 @mikehardy but we found a workaround with this version.

We now always call the getToken with forceRefresh true directly after the initalization of App Check: const { token } = await firebase.appCheck().getToken(true);

And now it works.

github-actions[bot] commented 2 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.