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

[🐛] [AppCheck] [Android] FIREBASE_APP_CHECK_DEBUG_TOKEN is not working #7405

Closed arsensgitacc closed 1 year ago

arsensgitacc commented 1 year ago

Issue

I am running FIREBASE_APP_CHECK_DEBUG_TOKEN='5056014B-362D-4180-A169-9BA84DEE69EC' react-native run-android and getting an error [Error: [appCheck/token-error] android.os.RemoteException: IntegrityService : Binder has died.] when calling my initAppCheck() function. Function is bellow.

const initAppCheck = async () => {
      if (isLoading) {
        const rnfbProvider =
          appCheck().newReactNativeFirebaseAppCheckProvider();
        rnfbProvider.configure({
          android: {provider: 'playIntegrity'},
          apple: {provider: 'appAttestWithDeviceCheckFallback'},
          isTokenAutoRefreshEnabled: true,
        });
        try {
          await appCheck().initializeAppCheck({
            provider: rnfbProvider,
            isTokenAutoRefreshEnabled: true,
          });
          const {token} = await appCheck().getToken(true);
          if (token.length > 0) {
            setLoading(false);
          }
        } catch (error) {
          console.log('AppCheck', 'Error on AppCheck init', error);
        }
      }
    };

I went through lib's android codes and FIREBASE_APP_CHECK_DEBUG_TOKEN is being got from envs and passed to BuildConfig

buildConfigField "String", "FIREBASE_APP_CHECK_DEBUG_TOKEN", "\"${System.env.FIREBASE_APP_CHECK_DEBUG_TOKEN}\""

But it's being used only in activate function, which is deprecated

@ReactMethod
  public void activate(
      String appName, String siteKeyProvider, boolean isTokenAutoRefreshEnabled, Promise promise) {
    try {

      FirebaseAppCheck firebaseAppCheck =
          FirebaseAppCheck.getInstance(FirebaseApp.getInstance(appName));
      firebaseAppCheck.setTokenAutoRefreshEnabled(isTokenAutoRefreshEnabled);

      // Configure our new proxy factory in a backwards-compatible way for old API
      if (isAppDebuggable()) {
        Log.d(LOGTAG, "app is debuggable, configuring AppCheck for testing mode");
        if (BuildConfig.FIREBASE_APP_CHECK_DEBUG_TOKEN != "null") {
          Log.d(LOGTAG, "debug app check token found in BuildConfig. Installing known token.");
          providerFactory.configure(appName, "debug", BuildConfig.FIREBASE_APP_CHECK_DEBUG_TOKEN);
        } else {
          Log.d(
              LOGTAG,
              "no debug app check token found in BuildConfig. Check Log for dynamic test token to"
                  + " configure in console.");
          providerFactory.configure(appName, "debug", null);
        }
      } else {
        providerFactory.configure(appName, "safetyNet", null);
      }

      FirebaseAppCheck.getInstance(FirebaseApp.getInstance(appName))
          .installAppCheckProviderFactory(providerFactory);
      promise.resolve(null);
    } catch (Exception e) {
      rejectPromiseWithCodeAndMessage(promise, "unknown", "internal-error", e.getMessage());
    }
  }

Project Files

Javascript

Click To Expand

#### `package.json`: ```json "@react-native-firebase/analytics": "18.5.0", "@react-native-firebase/app": "18.5.0", "@react-native-firebase/app-check": "18.5.0", "@react-native-firebase/auth": "18.5.0", "@react-native-firebase/crashlytics": "18.5.0", "@react-native-firebase/dynamic-links": "18.5.0", "@react-native-firebase/messaging": "18.5.0", "@react-native-firebase/perf": "18.5.0", "@react-native-firebase/remote-config": "18.5.0", ``` #### `firebase.json` for react-native-firebase v6: ```json { "react-native": { "crashlytics_disable_auto_disabler": true, "crashlytics_debug_enabled": true, "crashlytics_auto_collection_enabled": true, "perf_auto_collection_enabled": true, "analytics_auto_collection_enabled": true } } ```

Environment

Click To Expand

**`react-native info` output:** ``` OS: macOS 13.6 CPU: (10) arm64 Apple M1 Pro Memory: 77.22 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 18.15.0 - /var/folders/9v/73q5mbtj4pz22j7l16wkrs280000gn/T/yarn--1697135375138-0.1936903178077174/node Yarn: 1.22.19 - /var/folders/9v/73q5mbtj4pz22j7l16wkrs280000gn/T/yarn--1697135375138-0.1936903178077174/yarn npm: 9.6.4 - /opt/homebrew/bin/npm Watchman: 2023.05.01.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.12.1 - /Users/arsenananikyan/.rvm/rubies/ruby-2.7.6/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4 Android SDK: Not Found IDEs: Android Studio: 2022.2 AI-222.4459.24.2221.9971841 Xcode: 14.3.1/14E300c - /usr/bin/xcodebuild Languages: Java: 11.0.19 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.13 => 0.71.13 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **Platform that you're experiencing the issue on**: - [ ] iOS - [ ] Android - [ ] **iOS** but have not tested behavior on Android - [x] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - `e.g. 18.5.0`


mikehardy commented 1 year ago

You may find more information if you connect the device you are reproducing this on to a developer machine so you may run commands on the device via adb, and follow adb logcat while you reproduce it.

I expect there will be a Java native stack trace somewhere in that adb logcat that will have more details, until then, I'm unsure - not enough information to go on.

arsensgitacc commented 1 year ago

@mikehardy we went with passing debugToken to JS by reading them from .env using react-native-config. This is a more reliable solution. As I'm not sure how this scenario is working right now, I'll close the issue, thanks.

mikehardy commented 1 year ago

Indeed, passing the debug token in JS is one of the main reasons I implemented a custom app check provider in react native firebase, so JS level configuration could work. I think it's much easier and fits better with the react-native style of doing things