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

Getting timeouts when testing RNF with detox (experimentalForceLongPolling setting support) #3269

Closed tad3j closed 4 years ago

tad3j commented 4 years ago

Issue

When testing RNF app with detox, I get 60 second timeout when app opens for the first time...and after that, the data loads and all of the test pass if I add a delay that compensates for that initial timeout (seems like the same issue as with cypress for web sdk, but there is a workaorund).

There are open issues on firebase-js-sdk and cypress for this, and seems like the solution is to add experimentalForceLongPolling flag to config. I've tried that with RNF, but it doesn't recognize that option (for testing web app in cypress this worked).

Is there any chance you could add support for experimentalForceLongPolling setting for firestore? (may get renamed to forceLongPolling after experimental release)

P.S.: Seems like your issue template is broken, it nests all files under javascript part.


Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "name": "mobile", "description": "Mobile app for Android and iOS OSs", "version": "0.0.41", "engines": { "node": "10" }, "dependencies": { "@notifee/react-native": "^0.2.0", "@react-native-community/async-storage": "^1.7.1", "@react-native-community/blur": "^3.4.1", "@react-native-community/datetimepicker": "^2.1.0", "@react-native-community/masked-view": "^0.1.6", "@react-native-firebase/app": "^6.3.4", "@react-native-firebase/auth": "^6.3.4", "@react-native-firebase/firestore": "^6.3.4", "@react-native-firebase/functions": "^6.3.4", "@react-native-firebase/messaging": "^6.3.4", "@react-navigation/drawer": "^5.0.0", "@react-navigation/material-bottom-tabs": "^5.0.0", "@react-navigation/material-top-tabs": "^5.0.0", "@react-navigation/native": "^5.0.0", "@react-navigation/routers": "^5.0.0", "@react-navigation/stack": "^5.0.0", "@tad3j/shared": "^0.0.35", "deep-equal": "^2.0.1", "formik": "^2.1.2", "jest": "^24.9.0", "moment": "^2.24.0", "prop-types": "^15.7.2", "react": "^16.12.0", "react-native": "^0.61.5", "react-native-appearance": "^0.3.2", "react-native-device-info": "^5.4.1", "react-native-elements": "^1.2.7", "react-native-gesture-handler": "^1.5.5", "react-native-interactable": "^2.0.1", "react-native-paper": "^3.5.1", "react-native-reanimated": "^1.7.0", "react-native-safe-area-context": "^0.7.3", "react-native-safe-area-view": "^1.0.0", "react-native-screens": "^2.0.0-alpha.33", "react-native-tab-view": "^2.13.0", "react-native-timeago": "^0.5.0", "react-native-ui-lib": "^4.2.2", "react-native-vector-icons": "^6.6.0", "react-native-webview": "^8.0.3", "react-navigation-redux-helpers": "^4.0.1", "react-redux": "^7.1.3", "redux": "^4.0.5", "redux-devtools-extension": "^2.13.8", "redux-logger": "^3.0.6", "redux-persist": "^6.0.0", "redux-saga": "^1.1.3", "redux-saga-firebase": "^0.15.0", "yup": "^0.28.0" }, "devDependencies": { "@babel/core": "^7.6.2", "@babel/runtime": "^7.6.2", "@carimus/metro-symlinked-deps": "^1.1.0", "babel-plugin-module-resolver": "^4.0.0", "detox": "^15.3.0", "metro-react-native-babel-preset": "^0.56.0", "patch-package": "^6.1.4", "react-native-testing-library": "^1.12.0", "react-test-renderer": "^16.12.0" }, "jest": { "preset": "react-native" }, "detox": { "test-runner": "jest", "configurations": { "android.emu.debug": { "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", "build": "cd android && gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", "type": "android.emulator", "device": { "avdName": "Android9_Nexus_6_API_28" } }, "android.emu.release": { "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", "build": "cd android && gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", "type": "android.emulator", "device": { "avdName": "Android9_Nexus_6_API_28" } } } } } ``` #### `firebase.json` for react-native-firebase v6: ```json { "emulators": { "functions": { "port": 5001 }, "firestore": { "port": 8080 } }, "firestore": { "rules": "firestore.rules" }, "hosting": { "public": "packages/web/build", "rewrites": [ { "source": "**", "destination": "/index.html" } ], "ignore": [ "firebase.json", "lerna.json", "**/.*", "**/node_modules/**" ] }, "functions": { "source": "./packages/functions" } } ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby # N/A ``` #### `AppDelegate.m`: ```objc // N/A ```


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [x ] 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 // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = "29.0.0" minSdkVersion = 18 compileSdkVersion = 29 targetSdkVersion = 29 googlePlayServicesVersion = "16.1.0" // default: "+" googlePlayServicesIidVersion = "17.0.0" firebaseVersion = "17.3.4" // default: "+" //supportLibVersion = "" // default: 23.1.1 } repositories { google() jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.google.gms:google-services:4.3.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { mavenLocal() maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url("$rootDir/../../../node_modules/react-native/android") } maven { // Android JSC is installed from npm url("$rootDir/../../../node_modules/jsc-android/dist") } google() jcenter() maven { url 'https://jitpack.io' } //DETOX maven { // All of Detox' artifacts are provided via the npm module url "$rootDir/../../../node_modules/detox/Detox-android" } } } ``` #### `android/app/build.gradle`: ```groovy apply plugin: "com.android.application" import com.android.build.OutputFile project.ext.react = [ entryFile : "index.js", enableHermes: false, // clean and rebuild if changing cliPath : "../../node_modules/react-native/cli.js", ] apply from: "../../../../node_modules/react-native/react.gradle" def enableSeparateBuildPerCPUArchitecture = false def enableProguardInReleaseBuilds = false def jscFlavor = 'org.webkit:android-jsc:+' def enableHermes = project.ext.react.get("enableHermes", false); android { compileSdkVersion rootProject.ext.compileSdkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } //TODO: fixes problem "More than one file was found with OS independent path 'lib/x86/libc++_shared.so'" - after I've added notifee packagingOptions { pickFirst 'lib/x86/libc++_shared.so' pickFirst 'lib/x86_64/libc++_shared.so' pickFirst 'lib/arm64-v8a/libc++_shared.so' pickFirst 'lib/armeabi-v7a/libc++_shared.so' } defaultConfig { applicationId "com.tradingsignally" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" aaptOptions { noCompress "tflite", "model" } multiDexEnabled true //DETOX // This will later be used to control the test apk build type testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } splits { abi { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } } signingConfigs { debug { storeFile file('debug.keystore') storePassword 'android' keyAlias 'androiddebugkey' keyPassword 'android' } } buildTypes { debug { signingConfig signingConfigs.debug } release { signingConfig signingConfigs.debug minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } // applicationVariants are e.g. debug, release applicationVariants.all { variant -> variant.outputs.each { output -> def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] def abi = output.getFilter(OutputFile.ABI) if (abi != null) { // null for the universal-debug, universal-release variants output.versionCodeOverride = versionCodes.get(abi) * 1048576 + defaultConfig.versionCode } } } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "com.facebook.react:react-native:+" // From node_modules implementation 'androidx.appcompat:appcompat:1.1.0-rc01' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02' if (enableHermes) { def hermesPath = "../../../../node_modules/hermes-engine/android/"; debugImplementation files(hermesPath + "hermes-debug.aar") releaseImplementation files(hermesPath + "hermes-release.aar") } else { implementation jscFlavor } //Tadej: fixes a failed build //https://developer.android.com/studio/build/multidex implementation 'androidx.multidex:multidex:2.0.1' //DETOX androidTestImplementation('com.wix:detox:+') { transitive = true } androidTestImplementation 'junit:junit:4.12' } task copyDownloadableDepsToLibs(type: Copy) { from configurations.compile into 'libs' } apply from: file("../../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) apply plugin: 'com.google.gms.google-services' //ICONS from react-native-vector-icons (react-native-elements) project.ext.vectoricons = [ iconFontNames: ['MaterialIcons.ttf', 'MaterialCommunityIcons.ttf', 'FontAwesome.ttf'] // Name of the font files you want to copy ] apply from: "../../../../node_modules/react-native-vector-icons/fonts.gradle" ``` #### `android/settings.gradle`: ```groovy rootProject.name = 'mobile' apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' ``` #### `MainApplication.java`: ```java package com.tradingsignally; import android.app.Application; import android.content.Context; import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.soloader.SoLoader; import java.lang.reflect.InvocationTargetException; import java.util.List; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); return packages; } @Override protected String getJSMainModuleName() { return "index"; } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); initializeFlipper(this); // Remove this line if you don't want Flipper enabled } /** * Loads Flipper in React Native templates. * * @param context */ private static void initializeFlipper(Context context) { if (BuildConfig.DEBUG) { try { /* We use reflection here to pick up the class that initializes Flipper, since Flipper library is not available in release mode */ Class aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper"); aClass.getMethod("initializeFlipper", Context.class).invoke(null, context); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: Windows 10 10.0.18362 CPU: (8) x64 Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz Memory: 640.33 MB / 15.89 GB Binaries: Node: 10.19.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.21.1 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 6.13.6 - C:\Users\Tadej\AppData\Roaming\npm\npm.CMD SDKs: Android SDK: API Levels: 28, 29 Build Tools: 19.1.0, 21.1.2, 23.0.1, 28.0.3, 29.0.0, 29.0.2 System Images: android-23 | Intel x86 Atom, android-24 | Google Play Intel x86 Atom, android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android- 29 | Google APIs Intel x86 Atom ``` - **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. 5.4.3` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y/N` & `VERSION`


Think react-native-firebase is great? Please consider supporting all of the project maintainers and contributors by donating via our Open Collective where all contributors can submit expenses. [Learn More]

Salakar commented 4 years ago

P.S.: Seems like your issue template is broken, it nests all files under javascript part.

Thanks for letting me know, I've pushed a fix for this


As for the original issue I'm not sure what could be causing any hanging, it's worth noting that our entire test suite for React Native Firebase is running on Detox (albeit an older version) without any hanging issues.

Is there any chance you could add support for experimentalForceLongPolling setting for firestore? (may get renamed to forceLongPolling after experimental release)

Could you point me to any docs or links that show how to implement support for this? I could look into it then

tad3j commented 4 years ago

Right, I've noticed you use detox as well, 12.5.0 vs 15.3.0 here. I wanted to test with your version today but currently cant (having problems deploying + local firestore emulator doesn't seem to work for me with RNF), so I'll test as soon as I can.

This is an experimental option so there is not much documentation about it, here is what I found on their website: https://firebase.google.com/docs/reference/js/firebase.firestore.Settings#optional-experimental-force-long-polling

It seems experimentalForceLongPolling is more of a temporary workaround (at least according to state of issue on cypress), so after reconsidering again, I guess detox may be the cause of the issue and not RNF, so maybe I should open an issue there instead...to solve the issue at it's roots (will look into this more when I can).

stale[bot] commented 4 years 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 the community's attention?

This issue will be closed in 15 days if no further activity occurs. Thank you for your contributions.

tad3j commented 4 years ago

Sorry for late reply. I've tested this again today with latest version of both and it seems like it's working without any issues (detox^16.1.1 and react-native-firebase^6.4.0).