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

[šŸ”„] Unable to reach callable cloud function - an internal error has occurred, DEADLINE_EXCEEDED, could not connect to the server #8043

Open parmy opened 1 month ago

parmy commented 1 month ago

Issue

The issues are identical to those described in this closed ticket: https://github.com/invertase/react-native-firebase/issues/6263.

Randomly I was seeing the same issues on Android ( java.util.concurrent.ExecutionException ) and on iOS (.An internal error has occurred, print and inspect the error details for more information ).

After a complete reset, Android has been working fine; although I did nothing other then cleared gradle and rebuuld.

For iOS, a clean build had things running for a while. But as soon as the Android app started to work, the iOS mysteriously stopped working and hasn't worked since.

Unfortunately the message "An internal error has occurred, print and inspect the error details for more information" doesn't help with where to dive in deeper.

I was hoping replacing the firebase json files would fix things, but those files in my project are already identical to the laetst available in the Firebase console.

iOS fails calling functions live or in the production server. There is a live version of the app which continues to works fine, which only adds to the confusion.


Project Files

Javascript

Click To Expand const addUserFunc = functions.httpsCallable('signUpUser');

const response = await addUserFunc({ email, password, type: userType }); <-- code fails here #### `package.json`: ```json "dependencies": { "@cometchat/chat-sdk-react-native": "^4.0.12", "@expo/metro-runtime": "~3.2.3", "@gorhom/bottom-sheet": "^4.6.4", "@notifee/react-native": "^9.0.2", "@react-native-async-storage/async-storage": "^2.0.0", "@react-native-clipboard/clipboard": "^1.14.2", "@react-native-community/datetimepicker": "^8.2.0", "@react-native-community/masked-view": "^0.1.11", "@react-native-firebase/app": "^20.5.0", "@react-native-firebase/auth": "^20.5.0", "@react-native-firebase/crashlytics": "^20.5.0", "@react-native-firebase/firestore": "^20.5.0", "@react-native-firebase/functions": "^20.5.0", "@react-native-firebase/messaging": "^20.5.0", "@react-native-firebase/storage": "^20.5.0", "@react-navigation/bottom-tabs": "^6.6.1", "@react-navigation/native": "^6.0.2", "@react-navigation/stack": "^6.4.1", "@rneui/base": "^4.0.0-rc.7", "@rneui/themed": "^4.0.0-rc.8", "expo": "~51.0.31", "expo-application": "~5.9.1", "expo-build-properties": "~0.12.5", "expo-constants": "~16.0.2", "expo-dev-client": "~4.0.26", "expo-device": "~6.0.2", "expo-image": "~1.13.0", "expo-image-manipulator": "~12.0.5", "expo-image-picker": "~15.0.7", "expo-linking": "~6.3.1", "expo-localization": "~15.0.3", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", "expo-status-bar": "~1.12.1", "expo-system-ui": "~3.0.7", "expo-updates": "~0.25.25", "expo-web-browser": "~13.0.3", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.5", "react-native-app-intro-slider": "^4.0.4", "react-native-gesture-handler": "~2.16.1", "react-native-image-crop-picker": "^0.41.2", "react-native-modal-datetime-picker": "^18.0.0", "react-native-permissions": "^4.1.5", "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.5", "react-native-screens": "3.31.1", "react-native-svg": "^15.7.1", "react-native-switch-selector": "^2.3.0", "react-native-web": "~0.19.10", "react-native-webview": "13.8.6", "reanimated-bottom-sheet": "^1.0.0-alpha.22", "ts-custom-error": "^3.3.1", "use-debounce": "^10.0.3", "with-rn-image-crop-picker": "^0.2.0" }, "devDependencies": { "@babel/core": "^7.19.3", "@firebase/rules-unit-testing": "^2.0.4", "@types/react": "~18.2.14", "@typescript-eslint/eslint-plugin": "^6.6.0", "@typescript-eslint/parser": "^6.6.0", "babel-plugin-inline-import": "^3.0.0", "cross-env": "^7.0.3", "eslint": "^8.26.0", "eslint-config-google": "^0.14.0", "expo-module-scripts": "^3.5.2", "firebase-admin": "^12.2.0", "patch-package": "^6.4.7", "postinstall-postinstall": "^2.1.0", "typescript": "~5.3.3" }, ``` #### `firebase.json` for react-native-firebase v6: ```json # N/A ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") require 'json' podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} ENV['RCT_NEW_ARCH_ENABLED'] = podfile_properties['newArchEnabled'] == 'true' ? '1' : '0' ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] platform :ios, podfile_properties['ios.deploymentTarget'] || '13.4' install! 'cocoapods', :deterministic_uuids => false prepare_react_native_project! # @generated begin bt-rn-permissions - expo prebuild (DO NOT MODIFY) sync- [numbers removed] 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') node_require('react-native-permissions/scripts/setup.rb') setup_permissions([ 'Notifications', 'PhotoLibrary']) # @generated end bt-rn-permissions target 'BT' do use_expo_modules! config = use_native_modules! use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS'] use_react_native!( :path => config[:reactNativePath], :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes', # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/..", :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false', ) post_install do |installer| react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false, :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true', ) # This is necessary for Xcode 14, because it signs resource bundles by default # when building for devices. installer.target_installation_results.pod_target_installation_results .each do |pod_name, target_installation_result| target_installation_result.resource_bundle_targets.each do |resource_bundle_target| resource_bundle_target.build_configurations.each do |config| config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' end end end end post_integrate do |installer| begin expo_patch_react_imports!(installer) rescue => e Pod::UI.warn e end end end ``` #### `AppDelegate.m`: ```objc // N/A ```


Android

Click To Expand Not sure how to complete this section. The React-Native App is from an Expo Template, as it's working at the moment I've not included any further details, but if they are required, I'll be happy to provide. #### 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`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 13.5.2 CPU: (10) arm64 Apple M1 Max Memory: 84.92 MB / 64.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 20.17.0 path: ~/.nvm/versions/node/v20.17.0/bin/node Yarn: Not Found npm: version: 10.8.2 path: ~/.nvm/versions/node/v20.17.0/bin/npm Watchman: version: 2024.06.24.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.15.2 path: /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 23.0 - iOS 17.0 - macOS 14.0 - tvOS 17.0 - watchOS 10.0 Android SDK: Not Found IDEs: Android Studio: 2024.1 AI-241.15989.150.2411.11948838 Xcode: version: 15.0.1/15A507 path: /usr/bin/xcodebuild Languages: Java: version: 19.0.1 path: /usr/bin/javac Ruby: version: 2.6.10 path: /usr/bin/ruby npmPackages: "@react-native-community/cli": Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.74.5 wanted: 0.74.5 react-native-macos: Not Found npmGlobalPackages: "*react-native*": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: true 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 - [X] Both - **`react-native-firebase` version you're using that has this issue:** - `20.5.0` - **`Firebase` module(s) you're using that has the issue:** - `@react-native-firebase/functions` - **Are you using `TypeScript`?** - `Y` & `5.3.3`

Additional information that may help you:

I've lauched the project in XCode, there's no additional information in the logs.

I've tried the following:

Changing info.plist from:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
        <key>NSAllowsLocalNetworking</key>
        <true/>
    </dict>

To:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSAllowsLocalNetworking</key>
        <true/>     
    </dict>
    <key>NSExceptionDomains</key>
    <dict>
    <key>firebaseapp.com</key>
    <dict>
        <key>NSIncludesSubdomains</key>
        <true/>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
        <key>NSExceptionRequiresForwardSecrecy</key>
        <false/>
        <key>NSRequiresCertificateTransparency</key>
        <false/>
    </dict>
    </dict>

Edited the Product Scheme Run option and added the following argument under Arguments Passed on Launch: "-FIRDebugEnabled", no additional logs were produced.

Any suggestions please? If you need any more information from me, please let me know. Many thanks in advance.


parmy commented 1 week ago

I have noticed quite a few similar issues in this repo and others, listed below:

https://github.com/invertase/react-native-firebase/issues/8060 https://github.com/invertase/react-native-firebase/issues/6475 https://github.com/invertase/react-native-firebase/issues/6777 https://github.com/invertase/react-native-firebase/issues/6263 https://github.com/firebase/firebase-tools/issues/5872

There are more, I've listed the above to demonstrate this is a real issue developers are facing. I spent a number of days on this and found a reasonable workaround.

Setup

I do not use EAS, all builds are local.

Quick Answer

More Details

  1. The issue I faced was sometimes my app would connect to FB and then it would suddenly stop. There was no consistent behaviour.
  2. When I added expo-device to the project, I discovered the only way for the app builds to have ExpoDevice included was to delete the apps from the devices and rebuild using "--clean" for example "npx expo run:android --clean"
  3. This made me wonder; as I've been trying to switch between local and remote FB, if something was caching on the device which caused conflicts and prevented the app connecting to a FB service
  4. I used "npx expo-doctor" to help tidy up the project. Then I made the changes and followed the invocation commands listed in "Quick Answer" above.
  5. For the devies and simulator, it was clear their was no network issue, as the apps loaded and where able to connect to the expo server and from the browser I was able to load the FB Emulator Console.

firebase.json - host bindings

  "emulators": {
    "auth": {
      "host": "0.0.0.0",
      "port": 9099
    },
    "functions": {
      "host": "0.0.0.0",
      "port": 5001
    },
    "firestore": {
      "host": "0.0.0.0",
      "port": 8080
    },
    "storage": {
      "host": "0.0.0.0",
      "port": 9199
    },
    "ui": {
      "enabled": true,
      "host": "0.0.0.0",
      "port": 4000      
    }

NOTE: adding host binding to "ui" is optional - if you want to connect/test connection to the FB Emulator console remotely.

firebase.js

import { isDevice } from 'expo-device';
...

const USE_EMULATOR = true; //This should be a app.config.ts or .env setting
const FIREBASE_EMUALTOR_URL = "192.168.x.x"; //This should be a app.config.ts or .env setting

if (__DEV__ && USE_EMULATOR) {
    console.log('Using emulators');

    if (Platform.OS === 'web') {
      connectFirestoreEmulator(firestore, 'localhost', 8080);
      connectAuthEmulator(auth, 'http://localhost:9099');
      connectFunctionsEmulator(functions, 'localhost', 5001);
      connectStorageEmulator(storage, 'localhost', 9199);
    } else {
      let host = isDevice
        ? FIREBASE_EMUALTOR_URL || 'localhost'
        : 'localhost';

      firestore.useEmulator(host, 8080);
      auth.useEmulator(`http://${host}:9099`);
      functions.useEmulator(host, 5001);
      storage.useEmulator(host, 9199);
    }
    console.log('Emulators connected');
} else {
    console.log('Using remote Firebase services');
}

NOTE: If you change USE_EMULATOR or FIREBASE_EMUALTOR_URL, please follow the instructions in Quick Answer (delete app, rebuild, restart expo clearing cache).

Preferred Fix

I'm not sure if this is an Expo issue or Firebase issue. It's fairly easy to replicate. Create a simple app and try an auth, function, firestore or storage request. Then chanage: USE_EMULATOR or FIREBASE_EMUALTOR_IP. You should find without following the instructions I presented in Quick Answer, FB requests will fail.

Hopefully someone has a better\cleaner solution, rather then having to delete the app, rebuild etc...

Conclusion

This was extremely frustrating and the workaround was found through persistance and possibly some luck. I hope someone finds this post helpful. It's been hassle free development for me for the past few days :-)